Skip to content

Commit

Permalink
Merge pull request #1490 from sveltejs/gh-1489
Browse files Browse the repository at this point in the history
fix dynamic component bindings (#1489)
  • Loading branch information
Rich-Harris authored May 24, 2018
2 parents 80077c1 + df60585 commit 012289a
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/compile/nodes/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ export default class Component extends Node {
}

statements.push(deindent`
if (${binding.prop} in ${binding.obj}) {
if (${binding.value.snippet} !== void 0) {
${name_initial_data}.${binding.name} = ${binding.value.snippet};
${name_updating}.${binding.name} = true;
}`
Expand All @@ -304,7 +304,7 @@ export default class Component extends Node {
updates.push(deindent`
if (!${name_updating}.${binding.name} && ${[...binding.value.dependencies].map((dependency: string) => `changed.${dependency}`).join(' || ')}) {
${name_changes}.${binding.name} = ${binding.value.snippet};
${name_updating}.${binding.name} = true;
${name_updating}.${binding.name} = ${binding.value.snippet} !== void 0;
}
`);
});
Expand All @@ -318,7 +318,7 @@ export default class Component extends Node {

// TODO use component.on('state', ...) instead of _bind
componentInitProperties.push(deindent`
_bind: function(changed, childState) {
_bind(changed, childState) {
var ${initialisers};
${builder}
${hasStoreBindings && `#component.store.set(newStoreState);`}
Expand All @@ -328,7 +328,7 @@ export default class Component extends Node {
`);

beforecreate = deindent`
#component.root._beforecreate.push(function() {
#component.root._beforecreate.push(() => {
${name}._bind({ ${this.bindings.map(b => `${b.name}: 1`).join(', ')} }, ${name}.get());
});
`;
Expand Down Expand Up @@ -406,6 +406,14 @@ export default class Component extends Node {
if (${switch_value}) {
${name} = new ${switch_value}(${switch_props}(ctx));
${this.bindings.length > 0 && deindent`
#component.root._beforecreate.push(() => {
const changed = {};
${this.bindings.map(binding => deindent`
if (${binding.value.snippet} === void 0) changed.${binding.name} = 1;`)}
${name}._bind(changed, ${name}.get());
});`}
${name}._fragment.c();
${this.children.map(child => child.remount(name))}
Expand Down Expand Up @@ -554,8 +562,8 @@ export default class Component extends Node {

const expression = (
this.name === 'svelte:self' ? this.compiler.name :
isDynamicComponent ? `((${this.expression.snippet}) || @missingComponent)` :
`%components-${this.name}`
(isDynamicComponent ? `((${this.expression.snippet}) || @missingComponent)` :
`%components-${this.name}`)
);

this.bindings.forEach(binding => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<p>green {foo}</p>

<script>
export default {
data() {
return {
foo: 'green'
};
}
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<p>red {foo}</p>

<script>
export default {
data() {
return {
foo: 'red'
};
}
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default {
data: {
x: true
},

html: `
<p>parent green</p>
<p>green green</p>
`,

test(assert, component, target) {
// TODO replace this with component.set({ foo: undefined }) post-#1488
// component.set({ foo: undefined });
// delete component._state.foo;

component.set({
x: false,
foo: undefined
});

assert.htmlEqual(target.innerHTML, `
<p>parent red</p>
<p>red red</p>
`);

component.set({
x: true,
foo: undefined
});

assert.htmlEqual(target.innerHTML, `
<p>parent green</p>
<p>green green</p>
`);
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<p>parent {foo}</p>
<svelte:component this="{x ? Green : Red}" bind:foo />

<script>
import Green from './Green.html';
import Red from './Red.html';

export default {
data() {
return {
Green,
Red
};
}
};
</script>

0 comments on commit 012289a

Please sign in to comment.