2016-08-08 12 views
7

Ich habe einen Winkel 2 Controller bekam, die wie folgt aussieht:Angular 2: Wie erkenne ich Attributänderungen an Eingabeattributen einer Komponente?

@Component({ 
    selector: 'my-component', 
    template: '<div>The value is: {{ value }}</div>', 
}) 
class MyComponent implements OnInit { 
    @Input() 
    value: string; 

    @Output 
    valueChange = new EventEmitter<number>(); 

    ngOnInit() { 
    this.valueChange.subscribe(value => { 
     console.log('new value:', value); // <-- does not get triggered 
    }); 
    } 
} 

Aber wenn der Wert von value Änderungen aus einer Vorlage Bindung:

<my-component [value]="someValue" /> <!-- valueChange not triggered! --> 

Das valueChange Ereignis ausgelöst wird nicht so, Obwohl die Vorlage korrekt aktualisiert wird und den neuen Wert anzeigt, weiß die Komponente nicht, dass sie geändert wurde.

Wie kann ich feststellen, wenn die Eingabe-Attribute auf meinem Controller geändert werden?

Antwort

2

Ich habe in der Lage gewesen, durch die Implementierung von OnChanges um das Problem zu umgehen:

ngOnChanges(changes) { 
    for (let key in changes) { 
    if (this[key + 'Change']) 
     this[key + 'Change'].emit(changes[key].currentValue); 
    } 
} 

, die das Change Ereignis, wenn Angular erkennt eine Änderung automatisch auslösen ... aber gibt es eine Möglichkeit, dies nativ zu tun?

12

Meiner Meinung nach ist für Ihre Komponente Ereignis an andere zu emittieren, so dass sie ihre Ansicht bei Bedarf aktualisieren würde, sollte es nur für Änderungen verwendet werden, die intern gesendet werden müssen (daher der Name Output). Das Auslösen eines Output Ereignisses auf Input Änderungen können unerwartetes Verhalten verursachen (wie jetzt, dass valueChange für alle Änderungen sowohl innerhalb als auch außerhalb ausgelöst wird, und nicht wirklich ein Output mehr).

In Ihrem Fall, wenn Sie Dinge tun möchten, wenn Sie Ihre value ändert, können Sie es ein Setter machen:

private _value: string; 
get value(): string { 
    return this._value; 
} 

@Input('value') 
set value(val: string) { 
    this._value = val; 
    console.log('new value:', value); // <-- do your logic here! 
} 
7

I Setter zur Erkennung verwendet haben, wenn die Eingangsvariablen geändert wurden. Sie haben die inputs Schlüssel in der @Component Dekorateur verwenden anstelle der @Input Erklärung zu bekommen dies funktioniert wie folgt:

@Component({ 
    selector: 'my-component', 
    template: '<div>The value is: {{ value }}</div>', 
    inputs: ['value'] 
}) 
class MyComponent { 
    private _value: string; 

    @Output 
    valueChange = new EventEmitter<number>(); 

    set value(value) { 
    this._value = value; 
    console.log('new value:', value); 
    this.valueChange.emit(value); 
    } 

    get value(value) { 
    return this._value; 
    } 
} 

Auch FYI, die Klassenmethode ist ngOnInit statt onInit.

+1

Sie können die Eigenschaft inputs für den \ @Component-Decorator * oder * verwenden. Sie können den \ @Input-Decorator für die Eigenschaft set verwenden. Sie beide arbeiten derzeit, und der \ @Input-Dekorator scheint der aktuelle bevorzugte Weg zu sein –

+0

Ein get Accessor sollte und kann keinen Wert haben, möchten Sie möglicherweise Ihre get-Methode zu erhalten 'Wert() {} ' Ich denke, zu aktualisieren Ihr '@ output' muss möglicherweise auch auf' @Output() 'aktualisiert werden –