2015-11-02 75 views
4

我想在绑定对象发生更新时收到通知。 这个plunk http://plnkr.co/edit/7thr0V演示我的问题。Aurelia绑定钩在自定义元素中的“嵌套”数据更新

详细信息: 我通过bind [data.bind]将一个对象“data”传递给一个自定义元素。如果我现在 更新数据中的一个属性,我会期待,调用 自定义元素中的“dataChanged”挂钩。 如果我从自定义元素模板中的绑定数据对象中显示属性,它会更新,因此绑定本身可以正常工作。

我的第二点责备是使用ObserverLocator,但它也不会触发嵌套更新。

在app.js目的:

this.data = { 
    nested: { 
    content: "Hello nested world!" 
    } 
}; 

定制元件CE的结合:

<require from="ce"></require> 
<ce data.bind="data"></ce> 

的ce.js部分:

@bindable data; 

constructor(observerLocator) { 
    this.observerLocator = observerLocator; 

    var subscription = this.observerLocator 
     .getObserver(this, 'data') 
     //.getObserver(this, 'data["nested"]["content"]') //Doesn't work 
     //.getObserver(this, 'data.nested.content') //Doesn't work 
     .subscribe(this.onChangeData); 
} 

onChangeData(newData, oldData) { 
    console.log('data changed from ', oldData, newData); 
} 

dataChanged(d) { 
    console.log("Changed", d); 
} 

在CE模板部分:

${data.nested.content} 

在app.js中,我以2个间隔更新数据对象。 第一个间隔每秒编辑一个“嵌套”属性。 每五秒钟的第二个时间间隔将数据对象设置为新的。 在第二个时间间隔,挂钩和观察者被调用, 但我想知道,当第一个时间间隔做任何改变。

setInterval(() => { 
    this.data.nested.content += "!"; 
}, 1000); 


setInterval(() => { 
    this.data = { 
    nested: { 
    content: "Hello nested world No. " + this.counter++ + "!" 
    } 
}; 
}, 5000); 

回答

4

ObserverLocator是奥里利亚的用于观察简单属性更改和阵列/图/设置突变裸机API。

有一个新的更高级的API,名为BindingEngine,您可以使用它来观察复杂的表达式。

下面是一个例子:https://gist.run?id=868a7611952b2e40f350

ce.html

<template> 
    ${data.nested.content} 


    <!-- debug logging --> 
    <h4>Observed Changes:</h4> 
    <div repeat.for="change of changes"><pre><code>${change}</code></pre></div> 
</template> 

ce.js

import { 
    bindable, 
    BindingEngine, 
    inject 
} from "aurelia-framework"; 

@inject(BindingEngine) 
export class Ce { 
    @bindable data; 

    changes = []; // debug logging 

    constructor(bindingEngine) { 
    this.bindingEngine = bindingEngine; 
    } 

    expressionChanged(newValue, oldValue) { 
    // debug logging: 
    this.changes.splice(0, 0, `expressionChanged: "${newValue}"`); 
    } 

    syncSubscription(subscribe) { 
    if (this.subscription) { 
     this.subscription.dispose(); 
     this.subscription = null; 
    } 
    if (subscribe && this.data) { 
     let observer = this.bindingEngine.expressionObserver(this.data, 'nested.content'); 
     this.subscription = observer.subscribe(::this.expressionChanged); 
    } 
    } 

    dataChanged(newValue, oldValue) { 
    // subscribe to new data instance 
    this.syncSubscription(true); 

    // debug logging: 
    this.changes.splice(0, 0, `dataChanged: ${JSON.stringify(newValue, null, 2)}`); 
    } 

    attached() { 
    // subscribe 
    this.syncSubscription(true); 
    } 

    detached() { 
    // unsubscribe (avoid memory leaks) 
    this.syncSubscription(false); 
    } 
} 

为什么不奥里利亚观察更改整个对象默认?

它在速度和内存方面太急于观察一切。并非所有浏览器都支持object.observe。

+0

谢谢!像魅力一样工作=) – jmenzel

+0

有没有办法获得对整个对象的引用,而不仅仅是旧的和新的值? – jmorc

相关问题