possible fix for #893

pull/902/head
Rich Harris 7 years ago
parent 0a7d39d08f
commit 5646df77ac

@ -61,7 +61,7 @@ export default function visitBinding(
type type
); );
let setter = getSetter(block, name, snippet, state.parentNode, attribute, dependencies, value); let setter = getSetter(generator, block, name, snippet, state.parentNode, attribute, dependencies, value);
let updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`; let updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`;
const needsLock = !isReadOnly && node.name !== 'input' || !/radio|checkbox|range|color/.test(type); // TODO others? const needsLock = !isReadOnly && node.name !== 'input' || !/radio|checkbox|range|color/.test(type); // TODO others?
@ -290,6 +290,7 @@ function getBindingGroup(generator: DomGenerator, value: Node) {
} }
function getSetter( function getSetter(
generator: DomGenerator,
block: Block, block: Block,
name: string, name: string,
snippet: string, snippet: string,
@ -319,6 +320,15 @@ function getSetter(
} }
if (attribute.value.type === 'MemberExpression') { if (attribute.value.type === 'MemberExpression') {
// This is a little confusing, and should probably be tidied up
// at some point. It addresses a tricky bug (#893), wherein
// Svelte tries to `set()` a computed property, which throws an
// error in dev mode. a) it's possible that we should be
// replacing computations with *their* dependencies, and b)
// we should probably populate `generator.readonly` sooner so
// that we don't have to do the `.some()` here
dependencies = dependencies.filter(prop => !generator.computations.some(computation => computation.key === prop));
return deindent` return deindent`
var state = #component.get(); var state = #component.get();
${snippet} = ${value}; ${snippet} = ${value};

@ -0,0 +1,32 @@
export default {
dev: true,
html: `
<select>
<option value='A'>A</option>
<option value='B'>B</option>
<option value='C'>C</option>
</select>
`,
test(assert, component, target, window) {
const select = target.querySelector('select');
const options = target.querySelectorAll('option');
const change = new window.Event('change');
options[1].selected = true;
select.dispatchEvent(change);
assert.equal(component.get('selected').letter, 'B');
assert.htmlEqual(target.innerHTML, `
<select>
<option value='A'>A</option>
<option value='B'>B</option>
<option value='C'>C</option>
</select>
B
`);
}
};

@ -0,0 +1,27 @@
<select bind:value="selected.letter">
{{#each uppercase as letter}}
<option value="{{letter}}">{{letter}}</option>
{{/each}}
</select>
{{selected.letter}}
<script>
export default {
data() {
return {
letters: [
'a',
'b',
'c'
],
selected: {
letter: ''
}
}
},
computed:{
uppercase: letters => letters.map(x => x.toUpperCase())
}
};
</script>
Loading…
Cancel
Save