如何在Angular 2中强制组件重新渲染? 为了调试目的与Redux工作,我想强制一个组件重新渲染它的视图,这是可能的吗?
当前回答
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();
}
}
其他回答
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();
}
}
tx,发现我需要的解决方案:
constructor(private zone:NgZone) {
// enable to for time travel
this.appStore.subscribe((state) => {
this.zone.run(() => {
console.log('enabled time travel');
});
});
运行zone.run将强制组件重新呈现
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).
我使用*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。
推荐文章
- NullInjectorError: AngularFirestore没有提供程序
- 如何在Angular2中截断文本?
- 如何在Angular2 ngSwitch语句中使用typescript enum值
- Angular CLI错误:serve命令需要在Angular项目中运行,但是找不到项目定义
- 找到合成属性@panelState。请在您的应用程序中包含“BrowserAnimationsModule”或“NoopAnimationsModule”。
- 在Angular中上传文件?
- 模板驱动表单和响应式表单之间的实际区别是什么?
- Angular 2+和debounce
- 如何以及在哪里使用::ng-deep?
- 禁用在角材质对话框区域外单击以关闭对话框(angular 4.0+版本)
- Angular 2模板中的标签是什么意思?
- 如何扩展/继承组件?
- 属性“of”在类型“typeof”的Observable上不存在
- 如何设置<iframe src="…">没有引起'不安全值'异常?
- 何时使用“npm start”,何时使用“ng serve”?