Bagaimana cara memaksa rendering ulang komponen dalam Angular 2? Untuk keperluan debug bekerja dengan Redux saya ingin memaksa komponen untuk merender ulang tampilan itu, apakah itu mungkin?
Bagaimana cara memaksa rendering ulang komponen dalam Angular 2? Untuk keperluan debug bekerja dengan Redux saya ingin memaksa komponen untuk merender ulang tampilan itu, apakah itu mungkin?
Jawaban:
Rendering terjadi setelah deteksi perubahan. Untuk memaksa deteksi perubahan, sehingga nilai properti komponen yang telah berubah disebarkan ke DOM (dan kemudian browser akan membuat perubahan itu dalam tampilan), berikut adalah beberapa opsi:
$rootScope.$digest()
- yaitu, periksa pohon komponen lengkap$rootScope.$apply(callback)
- yaitu, mengevaluasi fungsi callback di dalam zona Angular 2. Saya pikir, tapi saya tidak yakin, bahwa ini akhirnya memeriksa struktur komponen lengkap setelah menjalankan fungsi callback.$scope.$digest()
- yaitu, periksa hanya komponen ini dan anak-anaknyaAnda akan perlu mengimpor dan kemudian menyuntikkan ApplicationRef
, NgZone
atau ChangeDetectorRef
ke dalam komponen Anda.
Untuk skenario khusus Anda, saya akan merekomendasikan opsi terakhir jika hanya satu komponen yang berubah.
this is the first time I am facing an update not working in ng2
. Strategi deteksi perubahan adalah default, jadi saya tahu saya belum mengacaukan strategi deteksi perubahan.
this
konteks yang tepat dalam panggilan balik POST.
pure:false
di dalam pipa. Ini berfungsi tetapi terlalu mahal (tidak efisien) untuk kasus penggunaan saya.
tx, temukan solusi yang saya butuhkan:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
running zone.run akan memaksa komponen untuk merender ulang
Pendekatan 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();
}
}
Saya paksa memuat ulang komponen saya menggunakan * ngIf.
Semua komponen di dalam wadah saya kembali ke kait siklus hidup penuh.
Dalam templat:
<ng-container *ngIf="_reload">
components here
</ng-container>
Kemudian di file ts:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
setTimeout()
. Sekarang milikku bekerja dengan solusi yang sederhana dan ringan!
Jawaban lain di sini memberikan solusi untuk memicu siklus deteksi perubahan yang akan memperbarui tampilan komponen (yang tidak sama dengan render penuh).
Re-render penuh, yang akan menghancurkan dan menginisialisasi ulang komponen (memanggil semua kait siklus hidup dan tampilan pembangunan kembali) dapat dilakukan dengan menggunakan ng-template
, ng-container
dan ViewContainerRef
dengan cara berikut:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
Kemudian dalam komponen memiliki referensi ke keduanya #outlet
dan #content
kami dapat menghapus konten outlet dan memasukkan instance komponen anak yang lain:
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
Selain itu, konten awal harus dimasukkan pada AfterContentInit
hook:
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
Solusi kerja lengkap dapat ditemukan di sini https://stackblitz.com/edit/angular-component-rerender .
ChangeDetectorRef.detectChanges()
biasanya cara paling fokus untuk melakukan ini. ApplicationRef.tick()
biasanya terlalu banyak pendekatan palu godam.
Untuk menggunakannya ChangeDetectorRef.detectChanges()
, Anda memerlukan ini di bagian atas komponen Anda:
import { ChangeDetectorRef } from '@angular/core';
... lalu, biasanya Anda menyebutkan itu ketika Anda menyuntikkannya dalam konstruktor Anda seperti ini:
constructor( private cdr: ChangeDetectorRef ) { ... }
Kemudian, di tempat yang tepat , Anda menyebutnya seperti ini:
this.cdr.detectChanges();
Tempat Anda menelepon ChangeDetectorRef.detectChanges()
bisa sangat signifikan. Anda harus benar - benar memahami siklus hidup dan bagaimana aplikasi Anda berfungsi dan menampilkan komponen-komponennya. Tidak ada pengganti di sini untuk benar-benar melakukan pekerjaan rumah Anda dan memastikan Anda memahami siklus hidup sudut luar. Kemudian, setelah Anda memahami itu, Anda dapat menggunakannya dengan ChangeDetectorRef.detectChanges()
tepat (kadang-kadang sangat mudah untuk memahami di mana Anda harus menggunakannya, di lain waktu itu bisa sangat kompleks).