Aurelia是否有AngularJS $手表替代品?

时间:2015-11-18 18:04:04

标签: javascript angularjs aurelia aurelia-binding

我正在尝试将当前的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有类似的东西?

3 个答案:

答案 0 :(得分:9)

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

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

  valueChanged(newValue, oldValue){
    //
  }
}

您也可以使用Aurelia作者博客here中所述的ObserveLocator

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}`);
  }
}

UPD

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

  

ObserverLocator是Aurelia的内部&#34;裸机&#34; 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();
  }
}

此致,亚历山大

答案 1 :(得分:7)

您的原始代码将使用一个小调整:

<强> 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有一个约定,它会在您的viewmodel上查找[propertyName]Changed方法并自动调用它。此约定与所有使用@bindable修饰的属性一起使用。更多信息here

答案 2 :(得分:1)

对于当前案例,似乎更好的解决方案是 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);
    }
}

你必须改变组件元素,添加一些触发你改变事件的触发器函数。我想该组件知道列表何时更改。