Làm cách nào để buộc kết xuất lại thành phần trong Angular 2? Đối với các mục đích gỡ lỗi làm việc với Redux, tôi muốn buộc một thành phần hiển thị lại chế độ xem của nó, điều đó có thể không?
Làm cách nào để buộc kết xuất lại thành phần trong Angular 2? Đối với các mục đích gỡ lỗi làm việc với Redux, tôi muốn buộc một thành phần hiển thị lại chế độ xem của nó, điều đó có thể không?
Câu trả lời:
Kết xuất xảy ra sau khi phát hiện thay đổi. Để buộc phát hiện thay đổi, để các giá trị thuộc tính thành phần đã thay đổi được truyền đến DOM (và sau đó trình duyệt sẽ hiển thị những thay đổi đó trong chế độ xem), đây là một số tùy chọn:
$rootScope.$digest()
- nghĩa là kiểm tra cây thành phần đầy đủ$rootScope.$apply(callback)
- tức là, đánh giá chức năng gọi lại bên trong vùng Angular 2. Tôi nghĩ, nhưng tôi không chắc chắn, điều này cuối cùng sẽ kiểm tra cây thành phần đầy đủ sau khi thực hiện chức năng gọi lại.$scope.$digest()
- tức là chỉ kiểm tra thành phần này và các phần tử con của nóBạn sẽ cần phải nhập khẩu và sau đó bơm ApplicationRef
, NgZone
hoặc ChangeDetectorRef
vào thành phần của bạn.
Đối với kịch bản cụ thể của bạn, tôi sẽ đề xuất tùy chọn cuối cùng nếu chỉ một thành phần duy nhất đã thay đổi.
this is the first time I am facing an update not working in ng2
. Chiến lược phát hiện thay đổi là mặc định vì vậy tôi biết rằng tôi đã không nhầm lẫn với chiến lược phát hiện thay đổi.
this
bối cảnh thích hợp trong cuộc gọi lại POST.
pure:false
đường ống. Nó hoạt động nhưng nó quá đắt (không hiệu quả) cho trường hợp sử dụng của tôi.
tx, tìm thấy cách giải quyết tôi cần:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
đang chạy area.run sẽ buộc thành phần kết xuất lại
Cách tiếp cận 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();
}
}
Tôi buộc tải lại thành phần của mình bằng cách sử dụng * ng If.
Tất cả các thành phần bên trong container của tôi quay trở lại các móc vòng đời đầy đủ.
Trong mẫu:
<ng-container *ngIf="_reload">
components here
</ng-container>
Sau đó trong tệp ts:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
setTimeout()
. Bây giờ tôi đang làm việc với một giải pháp đơn giản và nhẹ!
Các câu trả lời khác ở đây cung cấp các giải pháp để kích hoạt các chu kỳ phát hiện thay đổi sẽ cập nhật chế độ xem của thành phần (không giống như kết xuất lại hoàn toàn).
Full tái render, đó sẽ phá hủy và khởi tạo lại thành phần (gọi tất cả các lưỡi câu vòng đời và xây dựng lại quan điểm) có thể được thực hiện bằng cách sử dụng ng-template
, ng-container
và ViewContainerRef
theo cách sau đây:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
Sau đó, trong thành phần có tham chiếu đến cả hai #outlet
và #content
chúng ta có thể xóa nội dung của các cửa hàng và chèn một phiên bản khác của thành phần con:
@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;
private rerender() {
this.outletRef.clear();
this.outletRef.createEmbeddedView(this.contentRef);
}
Ngoài ra, nội dung ban đầu nên được chèn vào AfterContentInit
hook:
ngAfterContentInit() {
this.outletRef.createEmbeddedView(this.contentRef);
}
Giải pháp làm việc đầy đủ có thể được tìm thấy ở đây https://stackblitz.com/edit/angular-component-rerender .
ChangeDetectorRef.detectChanges()
thường là cách tập trung nhất để làm điều này. ApplicationRef.tick()
thường là quá nhiều của một cách tiếp cận búa tạ.
Để sử dụng ChangeDetectorRef.detectChanges()
, bạn sẽ cần thứ này ở đầu thành phần của bạn:
import { ChangeDetectorRef } from '@angular/core';
... sau đó, thông thường bạn sẽ bí danh rằng khi bạn tiêm nó vào hàm tạo của bạn như thế này:
constructor( private cdr: ChangeDetectorRef ) { ... }
Sau đó, ở nơi thích hợp , bạn gọi nó như thế này:
this.cdr.detectChanges();
Nơi bạn gọi ChangeDetectorRef.detectChanges()
có thể rất có ý nghĩa. Bạn cần hiểu hoàn toàn vòng đời và chính xác cách ứng dụng của bạn hoạt động và hiển thị các thành phần của nó. Không có sự thay thế nào ở đây để hoàn thành bài tập về nhà của bạn và đảm bảo bạn hiểu được vòng đời Angular từ trong ra ngoài. Sau đó, khi bạn hiểu điều đó, bạn có thể sử dụng ChangeDetectorRef.detectChanges()
một cách thích hợp (đôi khi rất dễ hiểu bạn nên sử dụng nó ở đâu, những lần khác có thể rất phức tạp).