Aurelia绑定挂钩“嵌套”自定义元素中的数据更新 [英] Aurelia binding hook on "nested" data update in custom element

查看:81
本文介绍了Aurelia绑定挂钩“嵌套”自定义元素中的数据更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在绑定对象中发生更新时收到通知。
这个插件 http://plnkr.co/edit/7thr0V 证明了我的问题。

I'm want to get notified, when a update happened in an binded object. This plunk http://plnkr.co/edit/7thr0V demonstrates my problem.

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

In more detail: I pass an object "data" via bind [data.bind] into a custom element. if i now update a property in data, i would expect, that the "dataChanged" hook in the custom element is called. If i show property from the binded data object in the custom elements template, it gets updated, so the binding itself works properly.

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

My second reproach is using the ObserverLocator, but it doesn't fire on nested updates, too.

app.js中的对象:

The object in app.js:

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

与自定义元素的绑定ce:

The binding to custom element 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个间隔更新数据对象。
每秒编辑一个嵌套属性的第一个间隔。
每五秒钟的第二个间隔将数据对象设置为new。
在第二个区间,钩子和观察者被调用,
但是我想要知道,当第一个区间做任何改变时。

In app.js I update the data object in 2 intervals. The first interval every second edit a "nested" property. The second interval every five seconds sets the data object new. On the second interval, the hooks and the observer get called, but I want a way to know, when the first intervals did any change.

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


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


推荐答案

ObserverLocator 是Aurelia的裸机API,用于观察简单的属性更改和数组/映射/集变异。

The ObserverLocator is Aurelia's bare metal API for observing simple property changes and array/map/set mutation.

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

There's a new, higher level API called the BindingEngine that you can use to observe complex expressions.

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

Here's an example: 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。

It's too expensive in terms of speed and memory to eagerly observe everything. Not all browsers support object.observe.

这篇关于Aurelia绑定挂钩“嵌套”自定义元素中的数据更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆