Wie erzwinge ich das erneute Rendern einer Komponente in Angular 2? Für Debug-Zwecke, die mit Redux arbeiten, möchte ich eine Komponente zwingen, ihre Ansicht neu zu rendern. Ist das möglich?
Wie erzwinge ich das erneute Rendern einer Komponente in Angular 2? Für Debug-Zwecke, die mit Redux arbeiten, möchte ich eine Komponente zwingen, ihre Ansicht neu zu rendern. Ist das möglich?
Antworten:
Das Rendern erfolgt nach der Änderungserkennung. Um die Änderungserkennung zu erzwingen, damit geänderte Werte von Komponenteneigenschaften an das DOM weitergegeben werden (und der Browser diese Änderungen dann in der Ansicht rendert), haben Sie folgende Optionen:
$rootScope.$digest()
- dh überprüfen Sie den vollständigen Komponentenbaum$rootScope.$apply(callback)
- dh die Rückruffunktion innerhalb der Angular 2-Zone auswerten. Ich denke, aber ich bin nicht sicher, ob dies dazu führt, dass der vollständige Komponentenbaum nach Ausführung der Rückruffunktion überprüft wird.$scope.$digest()
- dh nur diese Komponente und ihre untergeordneten Komponenten überprüfenSie müssen importieren und dann spritzen ApplicationRef
, NgZone
oderChangeDetectorRef
in Ihrer Komponente.
Für Ihr spezielles Szenario würde ich die letzte Option empfehlen, wenn sich nur eine einzelne Komponente geändert hat.
this is the first time I am facing an update not working in ng2
. Die Änderungserkennungsstrategie ist Standard, daher weiß ich, dass ich die Änderungserkennungsstrategie nicht durcheinander gebracht habe.
this
Kontexts im POST-Rückruf.
pure:false
in der Pipe versucht . Es funktioniert, ist aber für meinen Anwendungsfall viel zu teuer (ineffizient).
tx, fand die Problemumgehung, die ich brauchte:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
Wenn Sie zone.run ausführen, wird die Komponente zum erneuten Rendern gezwungen
ChangeDetectorRef-Ansatz
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();
}
}
Ich erzwinge das Neuladen meiner Komponente mit * ngIf.
Alle Komponenten in meinem Container gehen auf die Hooks für den gesamten Lebenszyklus zurück.
In der Vorlage:
<ng-container *ngIf="_reload">
components here
</ng-container>
Dann in der ts-Datei:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
setTimeout()
. Jetzt arbeitet meine mit einer einfachen und leichten Lösung!
Andere Antworten hier bieten Lösungen zum Auslösen von Änderungserkennungszyklen, mit denen die Ansicht der Komponente aktualisiert wird (was nicht mit dem vollständigen erneuten Rendern identisch ist).
Vollständige Wieder macht, die zerstören und neu zu initialisieren Komponente (Aufruf all Lifecycle - Haken und Wiederaufbau Ansicht) kann durch die Verwendung durchgeführt werden ng-template
, ng-container
und ViewContainerRef
in folgenden Weise:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
Dann in der Komponente Bezug auf den beiden #outlet
und #content
wir können Steckdosen Inhalt löschen und eine neue Instanz der Kinderkomponente einfügen:
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
Zusätzlich sollte der anfängliche Inhalt am AfterContentInit
Haken eingefügt werden :
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
Eine voll funktionsfähige Lösung finden Sie hier https://stackblitz.com/edit/angular-component-rerender .
ChangeDetectorRef.detectChanges()
ist normalerweise der konzentrierteste Weg, dies zu tun. ApplicationRef.tick()
ist in der Regel zu viel Vorschlaghammer Ansatz.
Zur Verwendung ChangeDetectorRef.detectChanges()
benötigen Sie dies oben in Ihrer Komponente:
import { ChangeDetectorRef } from '@angular/core';
... dann haben Sie normalerweise den Alias, wenn Sie es wie folgt in Ihren Konstruktor injizieren:
constructor( private cdr: ChangeDetectorRef ) { ... }
Dann nennen Sie es an der richtigen Stelle so:
this.cdr.detectChanges();
Wo Sie anrufen, ChangeDetectorRef.detectChanges()
kann von großer Bedeutung sein. Sie müssen den Lebenszyklus und die Funktionsweise Ihrer Anwendung vollständig verstehen und ihre Komponenten rendern. Es gibt hier keinen Ersatz dafür, Ihre Hausaufgaben vollständig zu erledigen und sicherzustellen, dass Sie den Angular-Lebenszyklus von innen nach außen verstehen. Sobald Sie das verstanden haben, können Sie es ChangeDetectorRef.detectChanges()
angemessen verwenden (manchmal ist es sehr einfach zu verstehen, wo Sie es verwenden sollten, manchmal kann es sehr komplex sein).