【问题标题】:Does Aurelia have an AngularJS $watch alternative?Aurelia 有 AngularJS $watch 替代品吗?
【发布时间】:2015-11-26 03:15:26
【问题描述】:

我正在尝试将我当前的 Angular.js 项目迁移到 Aurelia.js。 我正在尝试做类似的事情:

report.js

export class Report {
       list = [];

       //TODO
       listChanged(newList, oldList){
             enter code here
       }
}

report.html

<template>
    <require from="component"></require>
    <component list.bind="list"></component>
</template>

所以问题是:如何检测列表何时更改?

在 Angular.js 中我可以做到

$scope.$watchCollection('list', (newVal, oldVal)=>{ my code });

也许 Aurelia 也有类似的东西?

【问题讨论】:

    标签: javascript angularjs aurelia


    【解决方案1】:

    对于@bindable 字段,只要更新list 值,就会调用listChanged(newValue, oldValue)。请看Aurelia docs

    @customAttribute('if')
    @templateController
    export class If {
      constructor(viewFactory, viewSlot){
        //
      }
    
      valueChanged(newValue, oldValue){
        //
      }
    }
    

    您也可以使用 ObserveLocator,如 Aurelia 作者的博文 here 中所述:

    import {ObserverLocator} from 'aurelia-binding';  // or 'aurelia-framework'
    
    @inject(ObserverLocator)
    class Foo {  
      constructor(observerLocator) {
        // the property we'll observe:
        this.bar = 'baz';
    
        // subscribe to the "bar" property's changes:
        var subscription = this.observerLocator
          .getObserver(this, 'bar')
          .subscribe(this.onChange);
      }
    
      onChange(newValue, oldValue) {
        alert(`bar changed from ${oldValue} to ${newValue}`);
      }
    }
    

    更新

    正如 Jeremy Danyow 在this question 中提到的:

    ObserverLocator 是 Aurelia 的内部“裸机”API。现在有一个可用于绑定引擎的公共 API:

    import {BindingEngine} from 'aurelia-binding'; // or from 'aurelia-framework'
    
    @inject(BindingEngine)
    export class ViewModel {
      constructor(bindingEngine) {
        this.obj = { foo: 'bar' };
    
        // subscribe
        let subscription = bindingEngine.propertyObserver(this.obj, 'foo')
          .subscribe((newValue, oldValue) => console.log(newValue));
    
        // unsubscribe
        subscription.dispose();
      }
    }
    

    最好的问候,亚历山大

    【讨论】:

    • 您不知道自定义事件的解决方案吗?
    【解决方案2】:

    您的原始代码只需稍作调整即可工作:

    report.js

    import {bindable} from 'aurelia-framework'; // or 'aurelia-binding'
    
    export class Report {
           @bindable list;  // decorate the list property with "bindable"
    
           // Aurelia will call this automatically
           listChanged(newList, oldList){
                 enter code here
           }
    }
    

    report.html

    <template>
        <require from="component"></require>
        <component list.bind="list"></component>
    </template>
    

    Aurelia 有一个约定,它将在您的视图模型上查找 [propertyName]Changed 方法并自动调用它。此约定用于所有以@bindable 装饰的属性。更多信息here

    【讨论】:

      【解决方案3】:

      目前的情况似乎更好的解决方案是CustomeEvent

      那么完整的解决方案应该是这样的

      report.html

      <template>
          <require from="component"></require>
          <component list.bind="list" change.trigger="listChanged($event)"></component>
      </template>
      

      component.js

      @inject(Element)
      export class ComponentCustomElement {
          @bindable list = [];
      
          //TODO invoke when you change the list
          listArrayChanged() {
              let e = new CustomEvent('change', {
                  detail: this.lis
              });
      
              this.element.dispatchEvent(e);
          }
      }
      

      您必须更改组件元素,添加一些触发功能来触发您更改事件。我想该组件知道列表何时更改。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-17
        • 2017-03-05
        • 2021-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-11
        相关资源
        最近更新 更多