fix: infinite loop when binding object in key block

pull/8405/head
xxkl1 4 years ago
parent a2170f5bd5
commit e638456621

@ -112,7 +112,7 @@ export default class InlineComponentWrapper extends Wrapper {
return; return;
} }
const ignores = extract_ignores_above_node(this.node); const ignores = extract_ignores_above_node(this.node);
this.renderer.component.push_ignores(ignores); this.renderer.component.push_ignores(ignores);
if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) { if (variable.reassigned || variable.export_name || variable.is_reactive_dependency) {
this.renderer.component.warn(this.node, compiler_warnings.reactive_component(name)); this.renderer.component.warn(this.node, compiler_warnings.reactive_component(name));
@ -309,6 +309,9 @@ export default class InlineComponentWrapper extends Wrapper {
}`); }`);
} }
const is_key_block_child = this.parent && this.parent.node.type === 'KeyBlock';
const key_called = '_called';
const munged_bindings = this.node.bindings.map(binding => { const munged_bindings = this.node.bindings.map(binding => {
component.has_reactive_assignments = true; component.has_reactive_assignments = true;
@ -397,7 +400,8 @@ export default class InlineComponentWrapper extends Wrapper {
component.partly_hoisted.push(body); component.partly_hoisted.push(body);
return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}));`; const run_call_back = is_key_block_child && x`!${block.name}.${key_called}`;
return b`@binding_callbacks.push(() => @bind(${this.var}, '${binding.name}', ${id}, ${run_call_back}));`;
}); });
const munged_handlers = this.node.handlers.map(handler => { const munged_handlers = this.node.handlers.map(handler => {
@ -523,9 +527,9 @@ export default class InlineComponentWrapper extends Wrapper {
${props && b`let ${props} = ${attribute_object};`}`} ${props && b`let ${props} = ${attribute_object};`}`}
${statements} ${statements}
${name} = new ${expression}(${component_opts}); ${name} = new ${expression}(${component_opts});
${munged_bindings} ${munged_bindings}
${munged_handlers} ${munged_handlers}
${is_key_block_child && x`${block.name}.${key_called} = true`}
`); `);
if (has_css_custom_properties) { if (has_css_custom_properties) {

@ -5,11 +5,13 @@ import { children, detach, start_hydrating, end_hydrating } from './dom';
import { transition_in } from './transitions'; import { transition_in } from './transitions';
import { T$$ } from './types'; import { T$$ } from './types';
export function bind(component, name, callback) { export function bind(component, name, callback, runCallback = true) {
const index = component.$$.props[name]; const index = component.$$.props[name];
if (index !== undefined) { if (index !== undefined) {
component.$$.bound[index] = callback; component.$$.bound[index] = callback;
callback(component.$$.ctx[index]); if (runCallback) {
callback(component.$$.ctx[index]);
}
} }
} }

@ -0,0 +1,7 @@
<script lang='ts'>
export let obj;
</script>
<p>
{obj.value}
</p>

@ -0,0 +1,4 @@
// fix: https://github.com/sveltejs/svelte/issues/8305
export default {
html: '<p>0</p>'
};

@ -0,0 +1,10 @@
<script>
import Component from './Component.svelte';
let obj = {
value: '0'
};
</script>
{#key obj}
<Component bind:obj={obj} />
{/key}
Loading…
Cancel
Save