Angular 2でコンポーネントの再レンダリングを強制する方法は?Reduxでのデバッグ目的で、コンポーネントにビューの再レンダリングを強制したいのですが、それは可能ですか?
Angular 2でコンポーネントの再レンダリングを強制する方法は?Reduxでのデバッグ目的で、コンポーネントにビューの再レンダリングを強制したいのですが、それは可能ですか?
回答:
レンダリングは変更の検出後に行われます。変更の検出を強制し、変更されたコンポーネントのプロパティ値がDOMに伝達されるように(そして、ブラウザーがそれらの変更をビューに表示するように)、いくつかのオプションを次に示します。
$rootScope.$digest()
-つまり、コンポーネントツリー全体をチェックします$rootScope.$apply(callback)
-つまり、Angular 2ゾーン内のコールバック関数を評価します。コールバック関数を実行した後、コンポーネントツリー全体をチェックすることになると思いますが、よくわかりません。$scope.$digest()
-つまり、このコンポーネントとその子のみをチェックしますあなたは、インポートして注入する必要がありますApplicationRef
、NgZone
またはChangeDetectorRef
あなたのコンポーネントに。
特定のシナリオでは、単一のコンポーネントのみが変更されている場合は、最後のオプションをお勧めします。
this is the first time I am facing an update not working in ng2
です。変更検出戦略はデフォルトなので、変更検出戦略に失敗していません。
this
は、POSTコールバックで適切なコンテキストを使用していないことです。
pure:false
ました。それは機能しますが、私のユースケースには高すぎます(非効率的)。
tx、私が必要とした回避策を見つけました:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
zone.runを実行すると、コンポーネントが強制的に再レンダリングされます
ChangeDetectorRefアプローチ
import { Component, OnInit, ChangeDetectorRef } from '@angular/core';
export class MyComponent {
constructor(private cdr: ChangeDetectorRef) { }
selected(item: any) {
if (item == 'Department')
this.isDepartment = true;
else
this.isDepartment = false;
this.cdr.detectChanges();
}
}
* ngIfを使用してコンポーネントを強制的にリロードします。
コンテナー内のすべてのコンポーネントは、完全なライフサイクルフックに戻ります。
テンプレート:
<ng-container *ngIf="_reload">
components here
</ng-container>
次にtsファイルで:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
setTimeout()
。今、私はシンプルで軽量なソリューションで働いています!
ここでの他の回答は、コンポーネントのビューを更新する変更検出サイクルをトリガーするためのソリューションを提供します(完全な再レンダリングとは異なります)。
フル、再レンダリングした破壊とコンポーネント再初期化します(すべてのライフサイクルフックを呼び出し、ビューの再構築)が使用して行うことができng-template
、ng-container
そしてViewContainerRef
次のように:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
次いで、成分の両方を参照すること#outlet
と#content
、我々は出口のコンテンツをクリアし、子コンポーネントの別のインスタンスを挿入することができます。
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
さらに、初期コンテンツをAfterContentInit
オンフックで挿入する必要があります。
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
完全に機能するソリューションは、https://stackblitz.com/edit/angular-component-rerenderにあります。
ChangeDetectorRef.detectChanges()
これは通常、最も集中した方法です。ApplicationRef.tick()
通常、あまりにも多くのハンマーアプローチです。
を使用するChangeDetectorRef.detectChanges()
には、コンポーネントの上部にこれが必要です。
import { ChangeDetectorRef } from '@angular/core';
...次に、通常は、次のようにコンストラクタに注入するときにエイリアスを作成します。
constructor( private cdr: ChangeDetectorRef ) { ... }
次に、適切な場所で、次のように呼び出します。
this.cdr.detectChanges();
電話をかける場所はChangeDetectorRef.detectChanges()
非常に重要です。ライフサイクルを完全に理解し、アプリケーションが機能してコンポーネントをレンダリングする方法を正確に理解する必要があります。ここで宿題を完全に行い、Angularライフサイクルを完全に理解することの代わりはありません。次に、それを理解したら、ChangeDetectorRef.detectChanges()
適切に使用できます(使用する場所を理解するのが非常に簡単な場合もあれば、非常に複雑な場合もあります)。