Merge pull request #2694 from sveltejs/gh-2444

invalidate dependencies of reactive declarations
pull/2698/head
Rich Harris 5 years ago committed by GitHub
commit db8d7007aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -772,18 +772,34 @@ export default class Component {
});
}
invalidate(name, value = name) {
invalidate(name, value) {
const variable = this.var_lookup.get(name);
if (variable && (variable.subscribable && variable.reassigned)) {
return `$$subscribe_${name}(), $$invalidate('${name}', ${value})`;
return `$$subscribe_${name}(), $$invalidate('${name}', ${value || name})`;
}
if (name[0] === '$' && name[1] !== '$') {
return `${name.slice(1)}.set(${name})`
}
return `$$invalidate('${name}', ${value})`;
if (value) {
return `$$invalidate('${name}', ${value})`;
}
// if this is a reactive declaration, invalidate dependencies recursively
const deps = new Set([name]);
deps.forEach(name => {
const reactive_declarations = this.reactive_declarations.filter(x => x.assignees.has(name));
reactive_declarations.forEach(declaration => {
declaration.dependencies.forEach(name => {
deps.add(name);
});
});
});
return Array.from(deps).map(n => `$$invalidate('${n}', ${n})`).join(', ');
}
rewrite_props(get_insert: (variable: Var) => string) {

@ -0,0 +1,125 @@
export default {
props: {
items: [
{ done: false, text: 'one' },
{ done: true, text: 'two' },
{ done: false, text: 'three' }
]
},
html: `
<div>
<input type="checkbox">
<input type="text"><p>one</p>
</div>
<div>
<input type="checkbox">
<input type="text"><p>two</p>
</div>
<div>
<input type="checkbox">
<input type="text"><p>three</p>
</div>
<p>remaining:one / done:two / remaining:three</p>
`,
ssrHtml: `
<div>
<input type="checkbox">
<input type="text" value=one><p>one</p>
</div>
<div>
<input type="checkbox" checked="">
<input type="text" value=two><p>two</p>
</div>
<div>
<input type="checkbox">
<input type="text" value=three><p>three</p>
</div>
<p>remaining:one / done:two / remaining:three</p>
`,
async test({ assert, component, target, window }) {
function set_text(i, text) {
const input = target.querySelectorAll('input[type="text"]')[i];
input.value = text;
input.dispatchEvent(new window.Event('input'));
}
function set_done(i, done) {
const input = target.querySelectorAll('input[type="checkbox"]')[i];
input.checked = done;
input.dispatchEvent(new window.Event('change'));
}
component.filter = 'remaining';
assert.htmlEqual(target.innerHTML, `
<div>
<input type="checkbox">
<input type="text"><p>one</p>
</div>
<div>
<input type="checkbox">
<input type="text"><p>three</p>
</div>
<p>remaining:one / done:two / remaining:three</p>
`);
await set_text(1, 'four');
assert.htmlEqual(target.innerHTML, `
<div>
<input type="checkbox">
<input type="text"><p>one</p>
</div>
<div>
<input type="checkbox">
<input type="text"><p>four</p>
</div>
<p>remaining:one / done:two / remaining:four</p>
`);
assert.deepEqual(component.items, [
{ done: false, text: 'one' },
{ done: true, text: 'two' },
{ done: false, text: 'four' }
]);
await set_done(0, true);
assert.htmlEqual(target.innerHTML, `
<div>
<input type="checkbox">
<input type="text"><p>four</p>
</div>
<p>done:one / done:two / remaining:four</p>
`);
assert.deepEqual(component.items, [
{ done: true, text: 'one' },
{ done: true, text: 'two' },
{ done: false, text: 'four' }
]);
component.filter = 'done';
assert.htmlEqual(target.innerHTML, `
<div>
<input type="checkbox">
<input type="text"><p>one</p>
</div>
<div>
<input type="checkbox">
<input type="text"><p>two</p>
</div>
<p>done:one / done:two / remaining:four</p>
`);
},
};

@ -0,0 +1,25 @@
<script>
export let items;
export let filter = 'all';
$: done = items.filter(item => item.done);
$: remaining = items.filter(item => !item.done);
$: filtered = (
filter === 'all' ? items :
filter === 'done' ? done :
remaining
);
$: summary = items.map(i => `${i.done ? 'done' : 'remaining'}:${i.text}`).join(' / ');
</script>
{#each filtered as item}
<div>
<input type="checkbox" bind:checked={item.done}>
<input type="text" bind:value={item.text}>
<p>{item.text}</p>
</div>
{/each}
<p>{summary}</p>
Loading…
Cancel
Save