Skip to content

Commit 87d4912

Browse files
committed
[fix] propagate bindings correctly
Fixes #8103 introduced through #7981 while keeping the referenced bug in that PR fixed. This expands the "are the values equal"-check from just member expressions (bind:foo={member.expression}) to all occasions, because in loop scenarios the ctx object is temporarily lagging behind when doing the $$invalidate call.
1 parent 3ba0e30 commit 87d4912

File tree

5 files changed

+32
-15
lines changed

5 files changed

+32
-15
lines changed

src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -373,17 +373,14 @@ export default class InlineComponentWrapper extends Wrapper {
373373
}
374374
`);
375375

376-
let invalidate_binding = b`
377-
${lhs} = #value;
378-
${renderer.invalidate(dependencies[0])};
376+
// Always check for equality, don't wait for the dirty check in invalidate later
377+
// as it may not be updated correctly yet in loop conditions.
378+
const invalidate_binding = b`
379+
if ($$self.$$.not_equal(${lhs}, #value)) {
380+
${lhs} = #value;
381+
${renderer.invalidate(dependencies[0])};
382+
}
379383
`;
380-
if (binding.expression.node.type === 'MemberExpression') {
381-
invalidate_binding = b`
382-
if ($$self.$$.not_equal(${lhs}, #value)) {
383-
${invalidate_binding}
384-
}
385-
`;
386-
}
387384

388385
const body = b`
389386
function ${id}(${params}) {
@@ -393,7 +390,7 @@ export default class InlineComponentWrapper extends Wrapper {
393390

394391
component.partly_hoisted.push(body);
395392

396-
return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}, ${snippet}));`;
393+
return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}));`;
397394
});
398395

399396
const munged_handlers = this.node.handlers.map(handler => {

src/runtime/internal/Component.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@ import { children, detach, start_hydrating, end_hydrating } from './dom';
55
import { transition_in } from './transitions';
66
import { T$$ } from './types';
77

8-
export function bind(component, name, callback, value) {
8+
export function bind(component, name, callback) {
99
const index = component.$$.props[name];
1010
if (index !== undefined) {
1111
component.$$.bound[index] = callback;
12-
if (value === undefined) {
13-
callback(component.$$.ctx[index]);
14-
}
12+
callback(component.$$.ctx[index]);
1513
}
1614
}
1715

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<script>
2+
export let value;
3+
value = "bar";
4+
</script>
5+
6+
Child component "{value}"<br />
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export default {
2+
async test({ assert, target }) {
3+
assert.htmlEqual(target.innerHTML, `
4+
Parent component "bar"<br />
5+
Child component "bar"<br />
6+
`);
7+
}
8+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<script>
2+
import Component from "./Component.svelte";
3+
4+
let value = "foo";
5+
</script>
6+
7+
Parent component "{value}"<br />
8+
<Component bind:value />

0 commit comments

Comments
 (0)