【问题标题】:Aurelia make bindable act as observable on object propertiesAurelia 使可绑定行为在对象属性上可观察
【发布时间】:2018-12-16 07:04:54
【问题描述】:

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

例如:

  import { observable } from 'aurelia-framework';

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

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

因此,如果其中一个颜色属性发生变化,那么它将触发 colorChanged。但在自定义元素中,我们有这样的可绑定对象:

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

  export class SecretMessageCustomElement {
    @bindable data;

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

那么 dataChanged 将不会在其属性更改时被调用。怎么解决?

【问题讨论】:

  • 我已经写了一个通用的解决方案,很快就会回答我的问题。

标签: observable aurelia bindable


【解决方案1】:

@observable 不观察属性

这里是一个例子:https://gist.run/?id=040775f06aba5e955afd362ee60863aa

@observable color = { rgb: '', hex: '' }

colorChanged(val) { }

colorChanged 不会在 rgb 或 hex 更改时更改,只有在重新分配整个颜色属性时才会更改。

【讨论】:

    【解决方案2】:

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

    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。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 2017-11-25
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多