次のコンポーネントがあるとします。
@Component({
selector: 'compA',
template: template: `<compB [item]=item></compB>`
})
export class CompA {
item:any;
updateItem():void {
item[name] = "updated name";
}
}
@Component({
selector: 'compB',
template: template: `<p>{{item[name]}}</p>`
})
export class CompB implements OnInit{
@Input() item: any;
someArray: any[];
ngOnInit():void {
someArray.Push("something");
}
}
完全なitem
オブジェクトが変更されない限り、angular2はitem
の変更を認識しないことを私が理解している限り、したがって、item
メソッドが呼び出されたときに、updateItem
の変更イベントを手動で発行したいと思います。そしてその後、angularが通常の方法で変更を検出したかのように、子コンポーネント、つまりCompB
を再レンダリングします。
現在、私が行っているのは、ngOnInit
のCompB
メソッドを実装し、updateItem
メソッド内でViewChild
リンクを介してそのメソッドを呼び出すことです。ストーリーのもう1つの部分は、実際のソースにsomeArray
のようなオブジェクトがあり、レンダリングごとにリセットしたいということです。ただし、再レンダリングによってリセットが確実に行われるかどうかはわかりませんsomeArray
。現在、ngOnInit
メソッドでそれらをリセットしています。
だから、私の質問は、親オブジェクトのより深い要素の変更に対して再レンダリングをトリガーするにはどうすればよいですか?
ありがとう
完全なアイテムオブジェクトが変更されない限り、angular2はアイテムの変更を認識しないことを理解している限り。
それはそれほど簡単ではありません。オブジェクトが変更されたときのngOnChanges
のトリガーと、子コンポーネントのDOM更新を区別する必要があります。 Angularは、item
が変更されたことを認識せず、ngOnChanges
ライフサイクルフックをトリガーしませんが、テンプレートでitem
の特定のプロパティを参照すると、DOMは引き続き更新されます。これは、オブジェクトへの参照は保持されます。したがって、この動作をさせるには:
その後、子コンポーネントを作成します。つまり、angularが通常の方法で変更を検出したかのように、CompBを再レンダリングします。
DOMには引き続き更新があるため、特に何もする必要はありません。
変更検出器を挿入して、次のようにトリガーできます。
@Component({
selector: 'compA',
template: template: `<compB [item]=item></compB>`
})
export class CompA {
item:any;
constructor(cd: ChangeDetectorRef) {}
updateItem():void {
item[name] = "updated name";
this.cd.detectChanges();
}
}
これにより、現在のコンポーネントとそのすべての子の変更検出がトリガーされます。
しかし、それはあなたのケースでは何の影響もありません Angularはitem
itの変更を検出しませんまだ変更検出を実行します =子のB
コンポーネントおよびDOMを更新の場合。
nlessを使用しますChangeDetectionStrategy.OnPush
。この場合、あなたのために行く方法は、ngDoCheck
のCompB
フックで手動チェックを行うことでしょう:
import { ChangeDetectorRef } from '@angular/core';
export class CompB implements OnInit{
@Input() item: any;
someArray: any[];
previous;
constructor(cd: ChangeDetectorRef) {}
ngOnInit():void {
this.previous = this.item.name;
someArray.Push("something");
}
ngDoCheck() {
if (this.previous !== this.item.name) {
this.cd.detectChanges();
}
}
}
詳細については、次の記事をご覧ください。
compBに別の入力を置くことができるので、CompAの項目のプロパティを変更する場合は、この入力の値を変更するだけです。
@Component({
selector: 'compA',
template: template: `<compB [item]=item [trigger]=trigger></compB>`
})
export class CompA {
item:any;
trigger: any;
updateItem():void {
item[name] = "updated name";
trigger = new Object();
}
}
@Component({
selector: 'compB',
template: template: `<p>{{item[name]}}</p>`
})
export class CompB implements OnInit{
@Input() item: any;
@Input() trigger: any;
}