From 44287f846ad8b73bcd00f15602056e75cc190daf Mon Sep 17 00:00:00 2001 From: Rich-Harris Date: Tue, 28 Mar 2017 12:29:51 -0400 Subject: [PATCH] recompute computed values with functions as dependencies (#413) --- src/generators/dom/index.js | 9 +++--- src/shared/index.js | 4 +++ .../_config.js | 10 +++++++ .../main.html | 28 +++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 test/generator/samples/computed-values-function-dependency/_config.js create mode 100644 test/generator/samples/computed-values-function-dependency/main.html diff --git a/src/generators/dom/index.js b/src/generators/dom/index.js index a51cb6feaf36..0ea040166d34 100644 --- a/src/generators/dom/index.js +++ b/src/generators/dom/index.js @@ -246,22 +246,23 @@ export default function dom ( parsed, source, options ) { if ( computations.length ) { const builder = new CodeBuilder(); + const differs = generator.helper( 'differs' ); computations.forEach( ({ key, deps }) => { builder.addBlock( deindent` - if ( isInitial || ${deps.map( dep => `( '${dep}' in newState && typeof state.${dep} === 'object' || state.${dep} !== oldState.${dep} )` ).join( ' || ' )} ) { + if ( isInitial || ${deps.map( dep => `( '${dep}' in newState && ${differs}( state.${dep}, oldState.${dep} ) )` ).join( ' || ' )} ) { state.${key} = newState.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} ); } ` ); }); builders.main.addBlock( deindent` - function ${generator.alias( 'applyComputations' )} ( state, newState, oldState, isInitial ) { + function ${generator.alias( 'recompute' )} ( state, newState, oldState, isInitial ) { ${builder} } ` ); - builders._set.addLine( `${generator.alias( 'applyComputations' )}( this._state, newState, oldState, false )` ); + builders._set.addLine( `${generator.alias( 'recompute' )}( this._state, newState, oldState, false )` ); } // TODO is the `if` necessary? @@ -349,7 +350,7 @@ export default function dom ( parsed, source, options ) { if ( templateProperties.computed ) { constructorBlock.addLine( - `${generator.alias( 'applyComputations' )}( this._state, this._state, {}, true );` + `${generator.alias( 'recompute' )}( this._state, this._state, {}, true );` ); } diff --git a/src/shared/index.js b/src/shared/index.js index 7f76df1b4559..529435821b21 100644 --- a/src/shared/index.js +++ b/src/shared/index.js @@ -3,6 +3,10 @@ export * from './methods.js'; export function noop () {} +export function differs ( a, b ) { + return ( a !== b ) || ( a && ( typeof a === 'object' ) || ( typeof a === 'function' ) ); +} + export function dispatchObservers ( component, group, newState, oldState ) { for ( var key in group ) { if ( !( key in newState ) ) continue; diff --git a/test/generator/samples/computed-values-function-dependency/_config.js b/test/generator/samples/computed-values-function-dependency/_config.js new file mode 100644 index 000000000000..38b716b4d7a2 --- /dev/null +++ b/test/generator/samples/computed-values-function-dependency/_config.js @@ -0,0 +1,10 @@ +export default { + html: '

2

', + + test ( assert, component, target ) { + component.set({ y: 2 }); + assert.equal( component.get( 'x' ), 4 ); + assert.equal( target.innerHTML, '

4

' ); + component.destroy(); + } +}; diff --git a/test/generator/samples/computed-values-function-dependency/main.html b/test/generator/samples/computed-values-function-dependency/main.html new file mode 100644 index 000000000000..d385bf6da896 --- /dev/null +++ b/test/generator/samples/computed-values-function-dependency/main.html @@ -0,0 +1,28 @@ +

{{x}}

+ + \ No newline at end of file