From 773686639799c2e5357514690d0ff4f998f72d9e Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Wed, 23 Nov 2016 15:57:51 -0500 Subject: [PATCH] better solution for preventing blowback with inter-component bindings, also fixes #19 --- compiler/generate/index.js | 4 --- .../visitors/attributes/binding/index.js | 16 +++++++---- .../Counter.html | 9 +++++++ .../_config.js | 27 +++++++++++++++++++ .../main.html | 16 +++++++++++ 5 files changed, 63 insertions(+), 9 deletions(-) create mode 100644 test/compiler/component-binding-parent-supercedes-child/Counter.html create mode 100644 test/compiler/component-binding-parent-supercedes-child/_config.js create mode 100644 test/compiler/component-binding-parent-supercedes-child/main.html diff --git a/compiler/generate/index.js b/compiler/generate/index.js index ec9c71be5f..d169ed29d9 100644 --- a/compiler/generate/index.js +++ b/compiler/generate/index.js @@ -260,13 +260,9 @@ export default function generate ( parsed, source, options ) { } setStatements.push( deindent` - if ( setting ) return; - - setting = true; dispatchObservers( observers.immediate, newState, oldState ); if ( mainFragment ) mainFragment.update( newState, state ); dispatchObservers( observers.deferred, newState, oldState ); - setting = false; ` ); const topLevelStatements = []; diff --git a/compiler/generate/visitors/attributes/binding/index.js b/compiler/generate/visitors/attributes/binding/index.js index d04c4801ed..447afb34b7 100644 --- a/compiler/generate/visitors/attributes/binding/index.js +++ b/compiler/generate/visitors/attributes/binding/index.js @@ -74,18 +74,24 @@ export default function createBinding ( generator, node, attribute, current, loc } if ( local.isComponent ) { + generator.hasComplexBindings = true; + local.init.push( deindent` var ${local.name}_updating = false; - ${local.name}.observe( '${attribute.name}', function ( value ) { - ${local.name}_updating = true; - ${setter} - ${local.name}_updating = false; + component.__bindings.push( function () { + ${local.name}.observe( '${attribute.name}', function ( value ) { + ${local.name}_updating = true; + ${setter} + ${local.name}_updating = false; + }); }); ` ); local.update.push( deindent` - if ( !${local.name}_updating ) ${local.name}.set({ ${attribute.name}: ${contextual ? attribute.value : `root.${attribute.value}`} }); + if ( !${local.name}_updating && '${parts[0]}' in changed ) { + ${local.name}.set({ ${attribute.name}: ${contextual ? attribute.value : `root.${attribute.value}`} }); + } ` ); } else { local.init.push( deindent` diff --git a/test/compiler/component-binding-parent-supercedes-child/Counter.html b/test/compiler/component-binding-parent-supercedes-child/Counter.html new file mode 100644 index 0000000000..d22f95d166 --- /dev/null +++ b/test/compiler/component-binding-parent-supercedes-child/Counter.html @@ -0,0 +1,9 @@ + + + diff --git a/test/compiler/component-binding-parent-supercedes-child/_config.js b/test/compiler/component-binding-parent-supercedes-child/_config.js new file mode 100644 index 0000000000..6fa49fce9f --- /dev/null +++ b/test/compiler/component-binding-parent-supercedes-child/_config.js @@ -0,0 +1,27 @@ +export default { + html: ` + +

count: 10

+ `, + + test ( assert, component, target, window ) { + const click = new window.MouseEvent( 'click' ); + const button = target.querySelector( 'button' ); + + button.dispatchEvent( click ); + + assert.equal( component.get( 'x' ), 11 ); + assert.htmlEqual( target.innerHTML, ` + +

count: 11

+ ` ); + + button.dispatchEvent( click ); + + assert.equal( component.get( 'x' ), 12 ); + assert.htmlEqual( target.innerHTML, ` + +

count: 12

+ ` ); + } +}; diff --git a/test/compiler/component-binding-parent-supercedes-child/main.html b/test/compiler/component-binding-parent-supercedes-child/main.html new file mode 100644 index 0000000000..8647718813 --- /dev/null +++ b/test/compiler/component-binding-parent-supercedes-child/main.html @@ -0,0 +1,16 @@ + +

count: {{x}}

+ +