Aurelia使可绑定行为在对象属性上可观察到 [英] Aurelia make bindable act as observable on object properties

查看:41
本文介绍了Aurelia使可绑定行为在对象属性上可观察到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Aurelia绑定中,如果在组件中我们对属性使用可观察的修饰,并且如果该属性是对象,那么我们将订阅该对象的所有属性.

In Aurelia binding if in a component we use observable decoration on a property, and if the property being an object, then we will subscribe to all properties of that object.

例如:

  import { observable } from 'aurelia-framework';

  export class Car {
    @observable color = {rgb: '', hex: ''};

    colorChanged(newValue, oldValue) {
      // this will fire whenever the 'color' property changes
    }
  }

因此,如果颜色属性之一发生更改,则它将触发colorChanged.但是在自定义元素中,我们具有如下可绑定对象:

So if one of the color properties changes, then it will fire colorChanged. But in custom elements we have bindables like this:

  import {bindable, bindingMode} from 'aurelia-framework';

  export class SecretMessageCustomElement {
    @bindable data;

    dataChanged () {
       // -------
    }
  }

然后,不会在其属性更改时调用dataChanged.该如何解决?

then dataChanged won't be called on its properties change. How can this be solved?

推荐答案

通过一些尝试,我编写了一些代码行来修复我的问题,并希望对其他人有所帮助.我已订阅和取消订阅发生的每个数据更改,并且每次都在每个字段上都进行了此订阅.所以这是解决方案:

With some tries, I have written some lines of code that fixed my issue and hope helping others. I have subscribed and unsubscribed on every data change occuring and made this subscription to be done on every field every time. So here is the solution:

import {
  bindable,
  BindingEngine
} from 'aurelia-framework';

@inject(Element, BindingEngine)
export class PaChartjs {
  @bindable data;
  @bindable options;

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

  bind() {
    this.observeObject(this.data, 'data');
    this.observeObject(this.options, 'options');
  }
  unbind() {
    this.unobserveObjects();
  }

  unobserveObjects(groups) {
    let self = this;
    if (!groups) {
      groups = Object.keys(this.subscriptions);
    }
    groups.forEach((groupitem, groupindex) => {
      this.subscriptions[groupitem].forEach((subitem, subindex) => {
        subitem.sub.dispose();
        delete self.subscriptions[subindex];
      }); //otherwise you'll bind twice next time
    });
  }

  observeObject(obj, group) {
    let self = this;
    if (!this.subscriptions) {
      this.subscriptions = [];
    }
    if (!this.subscriptions[group]) {
      this.subscriptions[group] = [];
    }
    Object.keys(obj).forEach((keyitem, keyindex) => {
      if (typeof obj[keyitem] === 'object' && obj[keyitem] !== null) {
        self.observeObject(obj[keyitem]);
      } else {
        this.subscriptions[group].push({
          obj: obj,
          property: keyitem,
          sub: this.bindingEngine
            .propertyObserver(obj, keyitem) //e.g. subscribe to obj
            .subscribe(() => this.objectPropertyChanged()) //subscribe to prop change
        });
      }
    });
  }

  objectPropertyChanged(newValue, oldValue) {
    this.heavyJobHandler(() => this.updateChartData());
  }

  dataChanged(newValue, oldValue) {
    this.unobserveObjects(['data']);
    if (this.chartObj) {
      this.chartObj.data = newValue;
      this.heavyJobHandler(() => this.updateChartData());
    }
    this.observeObject(this.data, 'data');
  }

  optionsChanged(newValue, oldValue) {
    this.unobserveObjects(['data']);
    if (this.chartObj) {
      this.chartObj.options = options;
      this.heavyJobHandler(() => this.updateChartData());
    }
    this.observeObject(this.options, 'options');
  }
}

尽管这是代码的一部分,但它具有主要思想.TG.

although this is part of code, it has the main idea. TG.

这篇关于Aurelia使可绑定行为在对象属性上可观察到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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