From 9a70ca78745588e385d18b907a270479c20ce605 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Thu, 15 Jun 2017 13:44:29 -0400 Subject: [PATCH] mark indirect dependencies of + // + // + // + // + // ...we need to know that `foo` depends on `bar` and `baz`, + // so that if `foo.qux` changes, we know that we need to + // mark `bar` and `baz` as dirty too + if (node.name === 'select') { + const value = node.attributes.find((attribute: Node) => attribute.name === 'value'); + if (value) { + // TODO does this also apply to e.g. ``? + const dependencies = block.findDependencies(value.value); + state.selectBindingDependencies = dependencies; + dependencies.forEach((prop: string) => { + generator.indirectDependencies.set(prop, new Set()); + }); + } else { + state.selectBindingDependencies = null; + } + } + const isComponent = generator.components.has(node.name) || node.name === ':Self'; @@ -239,27 +293,6 @@ const preprocessors = { }); } - node.attributes.forEach((attribute: Node) => { - if (attribute.type === 'Attribute' && attribute.value !== true) { - attribute.value.forEach((chunk: Node) => { - if (chunk.type !== 'Text') { - const dependencies = block.findDependencies(chunk.expression); - block.addDependencies(dependencies); - } - }); - } else if (attribute.type === 'Binding') { - const dependencies = block.findDependencies(attribute.value); - block.addDependencies(dependencies); - } else if (attribute.type === 'Transition') { - if (attribute.intro) - generator.hasIntroTransitions = block.hasIntroMethod = true; - if (attribute.outro) { - generator.hasOutroTransitions = block.hasOutroMethod = true; - block.outros += 1; - } - } - }); - if (node.children.length) { if (isComponent) { const name = block.getUniqueName( diff --git a/src/generators/dom/visitors/shared/binding/getSetter.ts b/src/generators/dom/visitors/shared/binding/getSetter.ts index 7ce77b4489..679d9005f6 100644 --- a/src/generators/dom/visitors/shared/binding/getSetter.ts +++ b/src/generators/dom/visitors/shared/binding/getSetter.ts @@ -25,7 +25,10 @@ export default function getSetter({ ${computed && `var state = ${block.component}.get();`} list[index]${tail} = ${value}; - ${block.component}._set({ ${prop}: ${block.component}.get( '${prop}' ) }); + ${computed ? + `${block.component}._set({ ${dependencies.map((prop: string) => `${prop}: state.${prop}`).join(', ')} });` : + `${block.component}._set({ ${dependencies.map((prop: string) => `${prop}: ${block.component}.get( '${prop}' )`).join(', ')} });` + } `; } @@ -35,7 +38,7 @@ export default function getSetter({ return deindent` var state = ${block.component}.get(); ${snippet} = ${value}; - ${block.component}._set({ ${name}: state.${name} }); + ${block.component}._set({ ${dependencies.map((prop: string) => `${prop}: state.${prop}`).join(', ')} }); `; } diff --git a/test/runtime/samples/binding-indirect/_config.js b/test/runtime/samples/binding-indirect/_config.js new file mode 100644 index 0000000000..9fdfa23a25 --- /dev/null +++ b/test/runtime/samples/binding-indirect/_config.js @@ -0,0 +1,91 @@ +const tasks = [ + { description: 'put your left leg in', done: false }, + { description: 'your left leg out', done: false }, + { description: 'in, out, in, out', done: false }, + { description: 'shake it all about', done: false } +]; + +export default { + 'skip-ssr': true, + allowES2015: true, + + data: { + tasks, + selected: tasks[0] + }, + + html: ` + + + + +

Pending tasks

+

put your left leg in

+

your left leg out

+

in, out, in, out

+

shake it all about

+ `, + + test(assert, component, target, window) { + const input = target.querySelector('input'); + const select = target.querySelector('select'); + const options = target.querySelectorAll('option'); + + const change = new window.Event('change'); + + input.checked = true; + input.dispatchEvent(change); + + assert.ok(component.get('tasks')[0].done); + assert.htmlEqual(target.innerHTML, ` + + + + +

Pending tasks

+

your left leg out

+

in, out, in, out

+

shake it all about

+ `); + + options[1].selected = true; + select.dispatchEvent(change); + assert.equal(component.get('selected'), tasks[1]); + assert.ok(!input.checked); + + input.checked = true; + input.dispatchEvent(change); + + assert.ok(component.get('tasks')[1].done); + assert.htmlEqual(target.innerHTML, ` + + + + +

Pending tasks

+

in, out, in, out

+

shake it all about

+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/binding-indirect/main.html b/test/runtime/samples/binding-indirect/main.html new file mode 100644 index 0000000000..e1ab12c82f --- /dev/null +++ b/test/runtime/samples/binding-indirect/main.html @@ -0,0 +1,14 @@ + + + + +

Pending tasks

+{{#each tasks.filter(t => !t.done) as task}} +

{{task.description}}

+{{/each}} \ No newline at end of file