繁体   English   中英

Aurelia绑定钩子在自定义元素中的“嵌套”数据更新

[英]Aurelia binding hook on “nested” data update in custom element

当绑定对象发生更新时,我想收到通知。 这个插件http://plnkr.co/edit/7thr0V演示了我的问题。

更详细:我通过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);

ObserverLocator是Aurelia的裸机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);
  }
}

为什么aurelia默认情况下不会观察整个对象的变化?

在速度和记忆力方面过于昂贵,急切地观察一切。 并非所有浏览器都支持object.observe。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM