diff --git a/src/compile/nodes/Binding.ts b/src/compile/nodes/Binding.ts index 2d88267e4d..40ad3bce5f 100644 --- a/src/compile/nodes/Binding.ts +++ b/src/compile/nodes/Binding.ts @@ -205,12 +205,11 @@ function getEventHandler( block: Block, name: string, snippet: string, - dependencies: string[], - value: string, - isContextual: boolean + dependencies: Set, + value: string ) { const storeDependencies = [...dependencies].filter(prop => prop[0] === '$').map(prop => prop.slice(1)); - dependencies = [...dependencies].filter(prop => prop[0] !== '$'); + let dependenciesArray = [...dependencies].filter(prop => prop[0] !== '$'); if (binding.isContextual) { const tail = binding.value.node.type === 'MemberExpression' @@ -224,7 +223,7 @@ function getEventHandler( usesState: true, usesStore: storeDependencies.length > 0, mutation: `${head}${tail} = ${value};`, - props: dependencies.map(prop => `${prop}: ctx.${prop}`), + props: dependenciesArray.map(prop => `${prop}: ctx.${prop}`), storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`) }; } @@ -237,14 +236,14 @@ function getEventHandler( // replacing computations with *their* dependencies, and b) // we should probably populate `component.target.readonly` sooner so // that we don't have to do the `.some()` here - dependencies = dependencies.filter(prop => !component.computations.some(computation => computation.key === prop)); + dependenciesArray = dependenciesArray.filter(prop => !component.computations.some(computation => computation.key === prop)); return { usesContext: false, usesState: true, usesStore: storeDependencies.length > 0, mutation: `${snippet} = ${value}`, - props: dependencies.map((prop: string) => `${prop}: ctx.${prop}`), + props: dependenciesArray.map((prop: string) => `${prop}: ctx.${prop}`), storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`) }; } diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts index bbea56e55e..23e118fd43 100644 --- a/src/compile/nodes/Element.ts +++ b/src/compile/nodes/Element.ts @@ -828,6 +828,7 @@ export default class Element extends Node { if (eventHandlerOrBindingUsesContext) { initialProps.push(`ctx`); block.builders.update.addLine(`${node}._svelte.ctx = ctx;`); + block.maintainContext = true; } if (initialProps.length) { diff --git a/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js b/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js new file mode 100644 index 0000000000..390d39ea8e --- /dev/null +++ b/test/runtime/samples/binding-input-checkbox-with-event-in-each/_config.js @@ -0,0 +1,39 @@ +export default { + data: { + cats: [ + { + name: "cat 0", + checked: false, + }, + { + name: "cat 1", + checked: false, + }, + ], + }, + + html: ` + + + `, + + test(assert, component, target, window) { + const { cats } = component.get(); + const newCats = cats.slice(); + newCats.push({ + name: "cat " + cats.length, + checked: false, + }); + component.set({ cats: newCats }); + + let inputs = target.querySelectorAll('input'); + assert.equal(inputs.length, 3); + + const event = new window.Event('change'); + inputs[0].checked = true; + inputs[0].dispatchEvent(event); + + inputs = target.querySelectorAll('input'); + assert.equal(inputs.length, 3); + } +}; diff --git a/test/runtime/samples/binding-input-checkbox-with-event-in-each/main.html b/test/runtime/samples/binding-input-checkbox-with-event-in-each/main.html new file mode 100644 index 0000000000..e555f4c4b6 --- /dev/null +++ b/test/runtime/samples/binding-input-checkbox-with-event-in-each/main.html @@ -0,0 +1,14 @@ +{#each cats as cat (cat.name)} + +{/each} + + \ No newline at end of file