recompute computed values with functions as dependencies (#413)

pull/416/head
Rich-Harris 8 years ago
parent b9d3c235e7
commit 44287f846a

@ -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 );`
);
}

@ -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;

@ -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