Aurelia bindingEngine.propertyObserver-检测由于对象更改而导致属性更改的时间

时间:2019-01-08 16:04:54

标签: javascript typescript aurelia

我们正在使用类似的代码来检测对特定对象属性的更改。

import {BindingEngine} from 'aurelia-framework';

class MyViewModel {
    static inject = [BindingEngine];

    constructor(bindingEngine) {
        this.bindingEngine = bindingEngine;
        this.myObject = {observeMe : 'Test' + new Date()};
    }

    attached() {
        this.subscription = this.bindingEngine
            .propertyObserver(this.myObject, 'observeMe')
            .subscribe((newValue, oldValue) => { 
                this.objectValueChanged(newValue, oldValue) 
            });

        setInterval(() => {
            this.myObject.observeMe = 'Test' + new Date();
        }, 2000);
    }

    detached() {
        this.subscription.dispose();
    }

    objectValueChanged(newValue, oldValue) {
        console.log(`observeMe value changed from: ${oldValue} to:${newValue}`);
    }
}

https://discourse.aurelia.io/t/how-to-observe-objects-in-aurelia-using-the-binding-engine/23

上面的示例可以正常工作,并且objectValueChanged上的属性observeMe被更改时,会触发this.myObject。但是,由于某些情况,有时我们希望替换整个对象,但仍然会触发事件。示例:

setInterval(() => {
    this.myObject = { observeMe : 'Test' + new Date()}
    //Object.assign does not work either
    //this.myObject = Object.assign({ observeMe : 'Test' + new Date()}, this.myObject);
}, 2000);

这不会触发objectValueChanged。如果我们需要同时捕获两个属性更改或整个对象都更改了,该怎么办呢?

现在,我们已经解决了它,方法是不创建新对象,而是替换这样的值。但是,如果我们也可以跟踪对象是否已更改,对我们来说将容易得多。

Object.keys(this.myObject).forEach((key) => {
    this.myObject[key] = newMyObject[key];
});

1 个答案:

答案 0 :(得分:2)

您可以在expressionObserver上使用BindingEngine来观察具有许多访问器的长路径。此处的沙盒示例:https://codesandbox.io/s/x3qz6w2k6w

基本绑定引擎提供了执行此操作的快捷方式,如下所示:

bindingEngine.createObserverFor(someObject, 'at.this.property.path');

该值将是路径中最终属性的值,默认情况下,它不受null / undefined的保护,因此如果沿路径进行任何属性访问,您将获得undefined返回null / undefined