如何强制组件在Angular 2中重新渲染?

时间:2016-01-30 18:22:45

标签: angular angular2-changedetection

如何强制组件在Angular 2中重新渲染? 出于调试目的,使用Redux我想强制组件重新渲染它的视图,这可能吗?

6 个答案:

答案 0 :(得分:189)

在更改检测后进行渲染。要强制进行更改检测,以便已更改的组件属性值传播到DOM(然后浏览器将在视图中呈现这些更改),以下是一些选项:

  • ApplicationRef.tick() - 类似于Angular 1' $rootScope.$digest() - 即检查完整的组件树
  • NgZone.run(callback) - 类似于$rootScope.$apply(callback) - 即评估Angular 2区域内的回调函数。我想,但我不确定,这会在执行回调函数后检查完整的组件树。
  • ChangeDetectorRef.detectChanges() - 与$scope.$digest()类似 - 即仅检查此组件及其子组件

您需要导入,然后将ApplicationRefNgZoneChangeDetectorRef注入您的组件。

对于您的特定情况,如果只有一个组件发生了变化,我会推荐最后一个选项。

答案 1 :(得分:44)

tx,找到了我需要的解决方法:

  constructor(private zone:NgZone) {
    // enable to for time travel
    this.appStore.subscribe((state) => {
        this.zone.run(() => {
            console.log('enabled time travel');
        });
    });

运行zone.run将强制组件重新渲染

答案 2 :(得分:11)

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();
    }

}

答案 3 :(得分:3)

这里的其他答案提供了触发变更检测周期的解决方案,这些周期将更新组件的视图(与完全重新渲染不同)。

可以通过以下方式使用ng-templateng-containerViewContainerRef来进行完全重新渲染,这将破坏并重新初始化组件(调用所有生命周期挂钩和重建视图): / p>

<div>
  <ng-container #outlet >
  </ng-container>
</div>

<ng-template #content>
  <child></child>
</ng-template>

然后在同时引用#outlet#content的组件中,我们可以清除商店的内容并插入另一个子组件实例:

@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处找到。

答案 4 :(得分:1)

ChangeDetectorRef.detectChanges()通常是最专注的方法。 ApplicationRef.tick()通常不是大锤方法。

要使用ChangeDetectorRef.detectChanges(),您需要在组件顶部:

import {  ChangeDetectorRef } from '@angular/core';

...然后,通常在将其注入到构造函数中时使用别名:

constructor( private cdr: ChangeDetectorRef ) { ... }

然后,在 合适的地方 中,您将其命名为:

this.cdr.detectChanges();

在何处,您称之为ChangeDetectorRef.detectChanges()的意义非常重大。您需要完全了解生命周期以及您的应用程序如何正常工作并呈现其组件。这里没有替代品可以完全完成您的作业,并确保您了解内在的Angular生命周期。然后,一旦您了解了这一点,就可以适当地使用ChangeDetectorRef.detectChanges()(有时很容易理解应在何处使用它,而有时却很复杂)。

答案 5 :(得分:-1)

我强制使用* ngIf重新加载组件。

容器中的所有组件都返回到整个生命周期挂钩。

在模板中:

<ng-container *ngIf="_reload">
    components here 
</ng-container>

然后在ts文件中:

public _reload = true;

private reload() {
    setTimeout(() => this._reload = false);
    setTimeout(() => this._reload = true);
}