typescript - bileşen girişi için iç içe geçmiş özelliğin değişimini tespit et
Basitleştirilmiş bir şekilde, benim bir Angular2 Bileşenim ve şöyle bir giriş nesnem var:
class MyObject{
Prop1:string;
Prop2:Number;
}
@Component()
export class MyComponent{
@Input() myObject: MyObject;
DoSomethingIfProp1Change(){
console.log(myObject.Prop1);
}
}
Prop1'in Hostcomponent'ten değişip değişmediğini nasıl tespit edebilirim ve ardından DoSomethingIfProp1Change metodunu MyComponent içinde nasıl çalıştırabilirim?
Cevap #1
Aslında, varsayılan olarak Angular2, değişiklikleri nesne içeriğiyle değil, nesne referansı güncellendiğinde tespit eder. Ancak bu varsayılan davranış, DoCheck arayüzü kullanılarak değiştirilebilir.
Sizin durumunuzda (myObject nesnesine bir özelliğin güncellendiğini tespit etmek), aşağıdaki yaklaşımı kullanabilirsiniz:
@Component({
selector: 'my-component',
(...)
})
export class MyComponent implements DoCheck {
@Input() myObject: MyObject;
differ: any;
constructor(differs: KeyValueDiffers) {
this.differ = differs.find([]).create(null);
}
ngDoCheck() {
var changes = this.differ.diff(this.myObject);
if (changes) {
changes.forEachChangedItem((elt) => {
if (elt.key === 'prop1') {
this.doSomethingIfProp1Change();
}
});
}
}
doSomethingIfProp1Change() {
console.log('doSomethingIfProp1Change');
}
}
prop1 özelliğinin değeri güncellendiğinde, doSomethingIfProp1Change yöntemi çağrılır.
Bu plunkr'a bakın: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.
Cevap #2
Abonelere bildirim desteğini sağlamak için gözlemlenebilirleri kullanabilirsiniz. Angular kendisi, iç nesne durumundaki değişiklikleri izlemeyi desteklemez.
class MyObject{
constructor() {
this.prop1Change$ = new Observable(observer =>
this._prop1Observer = observer).share(); // share() allows multiple subscribers
this.prop2Change$ = new Observable(observer =>
this._prop2Observer = observer).share();
console.debug(this._prop2Observer);
}
prop1Change$: Observable<string>;
private _prop1Observer: Observer;
_prop1:string;
get prop1():string { return this._prop1 };
set prop1(value:string) {
this._prop1 = value;
this._prop1Observer && this._prop1Observer.next(value);
}
prop1Change$: Observable<number>;
private _prop2Observer: Observer;
_prop2:Number;
get prop2():number { return this._prop2 };
set prop2(value:number) {
this._prop2 = value;
console.debug(this);
this._prop2Observer && this._prop2Observer.next(value);
}
}
Bu kod Subject kullanılarak kısaltılabilir, ancak Observable Subject'in yerine tercih edilmelidir.
@Component()
export class MyComponent{
@Input() myObject: MyObject;
count2:number;
DoSomethingIfProp1Change(){
console.log(myObject.prop1);
}
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
console.log('changes');
if(changes['myObject']) {
if(this.prop2Subscription) {
this.prop2Subscription.unsubscribe();
}
this.prop2Subscription = this.myObject.prop2Change$.subscribe(value => {
this.count2 = value;
console.log('count2: ' + value);
});
// same for `prop2`
}
}
}
Plunker örneği
Ayrıca Bakınız Delegasyon: Angular2'de EventEmitter veya Observable
