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

如何强制组件';s在Angular 2中重新渲染?,angular,angular2-changedetection,Angular,Angular2 Changedetection,如何强制组件在Angular 2中重新渲染? 出于调试目的,在使用Redux时,我想强制组件重新呈现其视图,这可能吗?tx,找到了我需要的解决方法: constructor(private zone:NgZone) { // enable to for time travel this.appStore.subscribe((state) => { this.zone.run(() => { console.log('ena

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

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

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

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

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

  • -类似于Angular 1的
    $rootScope.$digest()
    ——即检查完整的组件树
  • -类似于
    $rootScope.$apply(回调)
    ——即,在Angular 2区域内计算回调函数。我认为,但我不确定,在执行回调函数后,这是否会检查完整的组件树
  • -类似于
    $scope.$digest()
    ——即只检查此组件及其子组件
您需要导入并将
ApplicationRef
NgZone
ChangeDetectorRef
注入组件


对于您的特定场景,如果只有一个组件发生了更改,我建议最后一个选项。

ChangeDetectorRef方法

从'@angular/core'导入{Component,OnInit,ChangeDetectorRef};
导出类MyComponent{
构造函数(私有cdr:ChangeDetectorRef){}
所选(项目:任何){
如果(项目==‘部门’)
this.isDepartment=true;
其他的
this.isDepartment=false;
this.cdr.detectChanges();
}
}

此处的其他答案提供了触发更改检测周期的解决方案,该周期将更新组件的视图(与完全重新渲染不同)

可以使用
ng template
ng container
ViewContainerRef
以以下方式完成完全重新渲染,这将销毁和重新初始化组件(调用所有生命周期挂钩并重建视图):

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

<ng-template #content>
  <child></child>
</ng-template>
此外,初始内容应插入到
AfterContentInit
hook:

ngAfterContentInit() {
    this.outletRef.createEmbeddedView(this.contentRef);
}

可以在这里找到完整的工作解决方案。

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

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

在模板中:

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

ChangeDetectorRef.detectChanges()
通常是最集中的方法
ApplicationRef.tick()
通常是一种过于繁琐的方法

要使用
ChangeDetectorRef.detectChanges()
,您需要在组件顶部添加以下内容:

@ViewChild("outlet", {read: ViewContainerRef}) outletRef: ViewContainerRef;
@ViewChild("content", {read: TemplateRef}) contentRef: TemplateRef<any>;

private rerender() {
    this.outletRef.clear();
    this.outletRef.createEmbeddedView(this.contentRef);
}
import {  ChangeDetectorRef } from '@angular/core';
。。。然后,通常在将其注入构造函数时使用别名,如下所示:

this.cdr.detectChanges();
构造函数(私有cdr:ChangeDetectorRef){…}

然后,在适当的地方,您可以这样称呼它:

this.cdr.detectChanges();

调用
ChangeDetectorRef.detectChanges()
的位置可能非常重要。您需要完全了解应用程序的生命周期,以及应用程序如何运行和呈现其组件。在这里,没有什么可以代替你完全做好你的功课,并确保你完全理解角度的生命周期。然后,一旦您理解了这一点,就可以适当地使用
changedtectorref.detectChanges()
(有时很容易理解应该在哪里使用它,有时它可能非常复杂)。

您所说的“重新渲染”是什么意思。更新绑定?只是一个简单的问题,为什么需要强制重新呈现?可能与此上下文中的appStore重复-哪种类型的变量及其类型?似乎可以观察到。。。但是我的可观察到的是在我想要在点击按钮时刷新的组件内部。。。我不知道如何从父/当前位置访问子组件方法/变量angular2最终版本的ChangeDetectorRef上的任何工作代码?我现在面临的情况是,在http的post请求创建新用户之后,视图没有更新,然后成功地将新对象推送到现有的旧用户列表(用于在视图中迭代)。非常奇怪,
这是我第一次面对不在ng2中工作的更新。更改检测策略是默认的,因此我知道我没有弄乱更改检测策略。@Gary,你应该发布一个新问题,并包括你的组件和服务代码(理想情况下,包括一个最小的plunker来演示该问题)。我看到的一个常见问题是在POST回调中没有使用正确的
this
上下文。您知道我是否可以在执行更改时手动触发管道吗?我已尝试触发更改检测,但管道未更新。。。我还尝试了管道中的
pure:false
。它可以工作,但对我的用例来说太贵(效率太低)。@n我不知道有什么方法可以手动触发管道更新。您可以使用纯管道并在需要触发更新时更改对象引用。本手册的“纯管道”一节对此进行了讨论。根据您的用例,您可能希望使用组件属性而不是管道。在管道文档的末尾简要讨论了这项技术。@N-ate,所有链接都已修复。谢谢,@loonis!我觉得这应该行得通,除了
setTimeout()
,我什么都有。现在我的正在使用一个简单而轻量级的解决方案!需要注意的一件事-容器消失和再次出现可能会导致大小变化,页面可能会闪烁