如何在Angular 2中强制组件重新渲染? 为了调试目的与Redux工作,我想强制一个组件重新渲染它的视图,这是可能的吗?
当前回答
这里的其他答案提供了触发更改检测周期的解决方案,该周期将更新组件的视图(这与完全重新渲染不同)。
完全重渲染,这将破坏和重新初始化组件(调用所有生命周期钩子和重建视图)可以通过以下方式使用ng-template, ng-container和ViewContainerRef完成:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
然后在同时引用#outlet和#content的组件中,我们可以清除outlet的内容并插入另一个子组件实例:
@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。
其他回答
呈现发生在变更检测之后。要强制更改检测,以便组件属性值的更改被传播到DOM(然后浏览器将在视图中呈现这些更改),以下是一些选项:
ApplicationRef.tick()——类似于Angular 1的$rootScope.$digest()——即检查完整的组件树 NgZone.run(回调)——类似于$rootScope.$apply(回调)——也就是说,计算Angular 2 zone内的回调函数。我认为,但我不确定,在执行回调函数后,这最终会检查完整的组件树。 ChangeDetectorRef.detectChanges()——类似于$scope.$digest()——也就是说,只检查这个组件及其子组件
你需要导入并注入ApplicationRef, NgZone或ChangeDetectorRef到你的组件中。
对于您的特定场景,如果只更改了一个组件,我建议使用最后一个选项。
tx,发现我需要的解决方案:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
运行zone.run将强制组件重新呈现
这里的其他答案提供了触发更改检测周期的解决方案,该周期将更新组件的视图(这与完全重新渲染不同)。
完全重渲染,这将破坏和重新初始化组件(调用所有生命周期钩子和重建视图)可以通过以下方式使用ng-template, ng-container和ViewContainerRef完成:
<div>
<ng-container #outlet >
</ng-container>
</div>
<ng-template #content>
<child></child>
</ng-template>
然后在同时引用#outlet和#content的组件中,我们可以清除outlet的内容并插入另一个子组件实例:
@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。
我使用*ngIf强制重载组件。
容器中的所有组件都返回到完整生命周期钩子。
在模板中:
<ng-container *ngIf="_reload">
components here
</ng-container>
然后在ts文件中:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
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();
}
}
推荐文章
- 如何刷新一个数据源(mat-table)
- 如何在Angular中动态加载外部脚本?
- 可观察到的。的不是一个函数
- Angular 2模板中的let-*是什么?
- 在Angular2中,圆括号、方括号和星号有什么区别?
- 当组件属性依赖于当前日期时间时,如何管理Angular2“expression has changed after it was checked”异常
- 如何部署Angular应用?
- 如何在Angular 2中强制组件重新渲染?
- 如何在Angular 2.0中使用/创建动态模板来编译动态组件?
- 如何启用生产模式?
- 如何使用this.router.parent.navigate('/about')导航到另一个路由?
- Take (1) vs first()
- module是什么意思?Id在组件中?
- 如果'<selector>'是一个Angular组件,那么验证它是这个模块的一部分
- Angular中相当于AngularJS $watch的东西是什么?