fix lazy select options bug

pull/10848/head
Simon Holthausen 2 years ago
parent 6717665b5d
commit b2cbb8d282

@ -642,9 +642,12 @@ function serialize_element_special_value_attribute(element, node_id, attribute,
)
);
const is_reactive = attribute.metadata.dynamic;
const is_select_with_reactive_value = element === 'select' && is_reactive;
const is_select_with_value =
// attribute.metadata.dynamic would give false negatives because even if the value does not change,
// the inner options could still change, so we need to always treat it as reactive
element === 'select' && attribute.value !== true && !is_text_attribute(attribute);
const assignment = b.stmt(
is_select_with_reactive_value
is_select_with_value
? b.sequence([
inner_assignment,
// This ensures a one-way street to the DOM in case it's <select {value}>
@ -656,7 +659,7 @@ function serialize_element_special_value_attribute(element, node_id, attribute,
: inner_assignment
);
if (is_select_with_reactive_value) {
if (is_select_with_value) {
state.init.push(b.stmt(b.call('$.init_select', node_id, b.thunk(value))));
}

@ -0,0 +1,16 @@
import { test } from '../../test';
export default test({
async test({ assert, target }) {
await target.querySelector('button')?.click();
await Promise.resolve();
const options = target.querySelectorAll('option');
assert.equal(options[0].selected, false);
assert.equal(options[1].selected, true);
assert.equal(options[2].selected, false);
assert.equal(options[3].selected, false);
assert.equal(options[4].selected, true);
assert.equal(options[5].selected, false);
}
});

@ -0,0 +1,33 @@
<script>
let value = 'bar';
let value_bound = 'bar';
let options = {};
function loadOptions() {
options = {
foo: 'Foo',
bar: 'Bar',
baz: 'Baz',
};
}
</script>
<select {value}>
{#each Object.entries(options) as [key, value] (key)}
<option value={key}>
{value}
</option>
{/each}
</select>
<select bind:value={value_bound}>
{#each Object.entries(options) as [key, value] (key)}
<option value={key}>
{value}
</option>
{/each}
</select>
<button on:click={loadOptions}>
Load options
</button>
Loading…
Cancel
Save