最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Does Aurelia have an AngularJS $watch alternative? - Stack Overflow

programmeradmin2浏览0评论

I'm trying to migrate my current Angular.js project to Aurelia.js. I'm trying to do something like that:

report.js

export class Report {
       list = [];

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

report.html

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

So the question is: how to detect when is the list changed?

In Angular.js I can do

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

Maybe Aurelia have something similar?

I'm trying to migrate my current Angular.js project to Aurelia.js. I'm trying to do something like that:

report.js

export class Report {
       list = [];

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

report.html

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

So the question is: how to detect when is the list changed?

In Angular.js I can do

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

Maybe Aurelia have something similar?

Share Improve this question edited Nov 18, 2015 at 20:24 Jeremy Danyow 26.4k12 gold badges90 silver badges135 bronze badges asked Nov 18, 2015 at 18:04 Egor MalkevichEgor Malkevich 1,5361 gold badge11 silver badges26 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 9

For @bindable fields the listChanged(newValue, oldValue) would be called whenever the list value is updated. Please take a look Aurelia docs

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

  valueChanged(newValue, oldValue){
    //
  }
}

You can also use ObserveLocator as described in Aurelia author's blogpost 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}`);
  }
}

UPD

As mentioned in this question by Jeremy Danyow:

The ObserverLocator is Aurelia's internal "bare metal" API. There's now a public API for the binding engine that could be used:

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

Best regards, Alexander

Your original code will work with one small tweak:

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="ponent"></require>
    <ponent list.bind="list"></ponent>
</template>

Aurelia has a convention that will look for a [propertyName]Changed method on your viewmodel and call it automatically. This convention is used with all properties decorated with @bindable. More info here

It seems better solution for current case is CustomeEvent

So plete solution would look like that

report.html

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

ponent.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);
    }
}

You have to change ponent element, add some trigger function that sand you change event. I suppose that ponent knows when list changed.

发布评论

评论列表(0)

  1. 暂无评论