Merge pull request #416 from sveltejs/gh-413

recompute computed values with functions as dependencies
pull/421/head
Rich Harris 8 years ago committed by GitHub
commit 731f840a34

@ -245,22 +245,23 @@ export default function dom ( parsed, source, options ) {
if ( computations.length ) { if ( computations.length ) {
const builder = new CodeBuilder(); const builder = new CodeBuilder();
const differs = generator.helper( 'differs' );
computations.forEach( ({ key, deps }) => { computations.forEach( ({ key, deps }) => {
builder.addBlock( deindent` 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( ', ' )} ); state.${key} = newState.${key} = ${generator.alias( 'template' )}.computed.${key}( ${deps.map( dep => `state.${dep}` ).join( ', ' )} );
} }
` ); ` );
}); });
builders.main.addBlock( deindent` builders.main.addBlock( deindent`
function ${generator.alias( 'applyComputations' )} ( state, newState, oldState, isInitial ) { function ${generator.alias( 'recompute' )} ( state, newState, oldState, isInitial ) {
${builder} ${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? // TODO is the `if` necessary?
@ -348,7 +349,7 @@ export default function dom ( parsed, source, options ) {
if ( templateProperties.computed ) { if ( templateProperties.computed ) {
constructorBlock.addLine( constructorBlock.addLine(
`${generator.alias( 'applyComputations' )}( this._state, this._state, {}, true );` `${generator.alias( 'recompute' )}( this._state, this._state, {}, true );`
); );
} }

@ -3,6 +3,10 @@ export * from './methods.js';
export function noop () {} 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 ) { export function dispatchObservers ( component, group, newState, oldState ) {
for ( var key in group ) { for ( var key in group ) {
if ( !( key in newState ) ) continue; if ( !( key in newState ) ) continue;

@ -0,0 +1,10 @@
export default {
html: '<p>2</p>',
test ( assert, component, target ) {
component.set({ y: 2 });
assert.equal( component.get( 'x' ), 4 );
assert.equal( target.innerHTML, '<p>4</p>' );
component.destroy();
}
};

@ -0,0 +1,28 @@
<p>{{x}}</p>
<script>
let _x;
function getX () {
return _x;
}
export default {
data () {
return {
y: 1
};
},
computed: {
xGetter ( y ) {
_x = y * 2;
return getX;
},
x ( xGetter ) {
return xGetter();
}
}
};
</script>
Loading…
Cancel
Save