如何在Angular 2中强制组件重新渲染? 为了调试目的与Redux工作,我想强制一个组件重新渲染它的视图,这是可能的吗?
当前回答
我使用*ngIf强制重载组件。
容器中的所有组件都返回到完整生命周期钩子。
在模板中:
<ng-container *ngIf="_reload">
components here
</ng-container>
然后在ts文件中:
public _reload = true;
private reload() {
setTimeout(() => this._reload = false);
setTimeout(() => this._reload = true);
}
其他回答
这里的其他答案提供了触发更改检测周期的解决方案,该周期将更新组件的视图(这与完全重新渲染不同)。
完全重渲染,这将破坏和重新初始化组件(调用所有生命周期钩子和重建视图)可以通过以下方式使用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。
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);
}
呈现发生在变更检测之后。要强制更改检测,以便组件属性值的更改被传播到DOM(然后浏览器将在视图中呈现这些更改),以下是一些选项:
ApplicationRef.tick()——类似于Angular 1的$rootScope.$digest()——即检查完整的组件树 NgZone.run(回调)——类似于$rootScope.$apply(回调)——也就是说,计算Angular 2 zone内的回调函数。我认为,但我不确定,在执行回调函数后,这最终会检查完整的组件树。 ChangeDetectorRef.detectChanges()——类似于$scope.$digest()——也就是说,只检查这个组件及其子组件
你需要导入并注入ApplicationRef, NgZone或ChangeDetectorRef到你的组件中。
对于您的特定场景,如果只更改了一个组件,我建议使用最后一个选项。
ChangeDetectorRef.detectChanges()通常是最专注的方法。ApplicationRef.tick()通常是一种大锤式的方法。
要使用ChangeDetectorRef.detectChanges(),你需要在你的组件顶部:
import { ChangeDetectorRef } from '@angular/core';
... 然后,通常当你在构造函数中注入它时,你会给它添加别名,就像这样:
构造函数(private cdr: ChangeDetectorRef){…}
然后,在适当的地方,像这样调用它:
this.cdr.detectChanges();
Where you call ChangeDetectorRef.detectChanges() can be highly significant. You need to completely understand the life cycle and exactly how your application is functioning and rendering its components. There's no substitute here for completely doing your homework and making sure you understand the Angular lifecycle inside out. Then, once you understand that, you can use ChangeDetectorRef.detectChanges() appropriately (sometimes it's very easy to understand where you should use it, other times it can be very complex).
推荐文章
- 当组件属性依赖于当前日期时间时,如何管理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的东西是什么?
- Angular 2没有base href设置
- 检查已安装的angular-cli版本?
- Angular:如何在不改变路由的情况下更新queryParams
- 当我通过浏览器刷新时,会出现Angular 2: 404错误
- Angular中的Subject vs behaviour Subject vs ReplaySubject