在Angular中手动触发变化检测

jz8*_*z87 352 angular2-changedetection angular

我正在编写一个具有属性的Angular组件Mode(): string.我希望能够以编程方式设置此属性,而不是响应任何事件.问题是在没有浏览器事件的情况下,模板绑定{{Mode}}不会更新.有没有办法手动触发此更改检测?

Mar*_*cok 587

尝试以下方法之一:

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

您可以注入ApplicationRef,NgZoneChangeDetectorRef注入组件.

  • 我以为我会提到这个.这些不是静态方法,它们是实例方法.您将需要将这些类作为服务注入. (47认同)
  • "ChangeDetectorRef.detectChanges()"的+1.验证器在我的指令更新输入值之前触发. (33认同)
  • ApplicationRef.tick()和ChangeDetectorRef.detectChanges()仍然存在于2.0.0 final中. (7认同)

jua*_*tas 113

我使用了接受的答案参考,并想举个例子,因为Angular 2文档非常难以阅读,我希望这更容易:

  1. 进口NgZone:

    import { Component, NgZone } from '@angular/core';
    
    Run Code Online (Sandbox Code Playgroud)
  2. 将它添加到类构造函数中

    constructor(public zone: NgZone, ...args){}
    
    Run Code Online (Sandbox Code Playgroud)
  3. 运行代码zone.run:

    this.zone.run(() => this.donations = donations)
    
    Run Code Online (Sandbox Code Playgroud)

  • 你应该把`zone.run`代码放在哪里,什么是'捐赠'? (6认同)
  • 使用document.addEventListener(“ resume”,callback)时,我使用此解决方案强制视图更新 (3认同)
  • @suku 捐赠是您想要更新的任何属性,因此它可以是 this.foo = bar。zone.run 可以随时随地更新内容。 (2认同)

Nun*_*mas 63

我能用markForCheck()更新它

导入ChangeDetectorRef

import { ChangeDetectorRef } from '@angular/core';
Run Code Online (Sandbox Code Playgroud)

注入并实例化它

constructor(private ref: ChangeDetectorRef) { 
}
Run Code Online (Sandbox Code Playgroud)

最后标记变化检测发生

this.ref.markForCheck();
Run Code Online (Sandbox Code Playgroud)

这是一个markForCheck()工作的例子,而detectChanges()则没有.

https://plnkr.co/edit/RfJwHqEVJcMU9ku9XNE7?p=preview

编辑:此示例不再描述问题:(我相信它可能正在运行更新的Angular版本,它已修复.

(按STOP/RUN再次运行)

  • 似乎detectChanges实际上在这个plunker工作?我错过了什么吗? (2认同)

Jer*_*ger 6

在Angular 2+中,尝试@Input装饰器

它允许在父组件和子组件之间进行一些不错的属性绑定。

首先在父级中创建一个全局变量,以保存将传递给子级的对象/属性。

接下来,在子级中创建一个全局变量,以保存从父级传递来的对象/属性。

然后在使用子模板的父html中,添加带有子变量名称的方括号符号,然后将其设置为与父变量的名称相同。例:

<child-component-template [childVariable] = parentVariable>
</child-component-template>
Run Code Online (Sandbox Code Playgroud)

最后,在子组件中定义子属性的地方,添加Input装饰器:

@Input()
public childVariable: any
Run Code Online (Sandbox Code Playgroud)

当您的父变量被更新时,它将更新传递给子组件,子组件将更新其html。

另外,要触发子组件中的功能,请查看ngOnChanges。

  • 不...那是问题...如果在父级中更新...例如exmaple是通过静态方法“通过引用”更新的,则子代不会选择它,因为尚未发生更改检测 (2认同)