2015-11-18 6 views
7

Ich versuche mein aktuelles Angular.js-Projekt nach Aurelia.js zu migrieren. Ich versuche, so etwas zu tun:

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> 

Die Frage ist also: Wie zu erkennen, wenn das ist Liste geändert?

In Angularjs kann ich

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

Vielleicht Aurelia haben etwas ähnliches?

Antwort

8

Für @bindable Felder würde die listChanged(newValue, oldValue) aufgerufen werden, wenn der list Wert aktualisiert wird. Bitte werfen Sie einen Blick Aurelia docs

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

    valueChanged(newValue, oldValue){ 
    // 
    } 
} 

Sie auch ObserveLocator wie beschrieben in Aurelia Autors Blogpost here verwenden:

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

Wie erwähnt in this question von Jeremy Danyow:

Der ObserverLocator ist Aurelias interna l "Bare Metal" API. Es gibt jetzt eine öffentliche API für die Bindung Engine, die verwendet werden könnten:

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

Mit freundlichen Grüßen, Alexander

+0

Wissen Sie nicht Lösung mit benutzerdefinierten Ereignissen? –

1

Es bessere Lösung für aktuelle Fall scheint ist CustomeEvent

So Komplettlösung würde so aussehen

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

Sie haben Komponentenelement zu ändern, fügen Sie einige Trigger-Funktion, dass Sand Sie Ereignis ändern. Ich nehme an, dass diese Komponente weiß, wann die Liste geändert wurde.

7

Ihr Original-Code wird mit einem kleinen zwicken arbeiten:

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 
     } 
} 

Bericht.html

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

Aurelia hat eine Konvention, die für eine [propertyName]Changed Methode auf Ihrem Viewmodel aussehen und es automatisch aufrufen. Diese Konvention wird mit allen Eigenschaften verwendet, die mit @bindable dekoriert sind. Weitere Informationen here