如何手动触发更改事件 - angular2
Posted
技术标签:
【中文标题】如何手动触发更改事件 - angular2【英文标题】:How to trigger a change event manually - angular2 【发布时间】:2017-12-10 00:45:46 【问题描述】:给定以下组件:
@Component(
selector: 'compA',
template: template: `<compB [item]=item></compB>`
)
export class CompA
item:any;
updateItem():void
item[name] = "updated name";
@Component(
selector: 'compB',
template: template: `<p>item[name]</p>`
)
export class CompB implements OnInit
@Input() item: any;
someArray: any[];
ngOnInit():void
someArray.push("something");
据我了解,除非更改完整的 item
对象,否则 angular2 无法识别 item
上的更改。因此,我想在调用updateItem
方法时为item
手动发出更改事件。然后,重新渲染子组件,即CompB
,就好像 Angular 以常规方式检测到变化一样。
目前,我所做的是实现CompB
的ngOnInit
方法,并通过ViewChild
链接在updateItem
方法中调用该方法。故事的另一部分是我的实际来源有像someArray
这样的对象,我想在每次渲染中重置它们。我不确定重新渲染是否会重置someArray
。目前,我正在ngOnInit
方法中重置它们。
所以,我的问题是:如何触发对父对象的更深元素的更改进行重新渲染?
谢谢
【问题讨论】:
Triggering Angular2 change detection manually的可能重复 @jonrsharpe ,我不想触发更改检测过程,我希望 Angular 能够识别更改,但其内置的更改识别机制无法检测到... @suat,检测到,见my answer。我添加了一些说明 【参考方案1】:据我了解,除非完整的 item 对象是 已更改,angular2 无法识别项目上的更改。
事情并不是那么简单。您必须区分对象发生变异时触发ngOnChanges
和子组件的DOM 更新。 Angular 无法识别 item
已更改并且不会触发 ngOnChanges
生命周期挂钩,但如果您在模板中引用 item
的特定属性,DOM 仍将更新。这是因为对对象的引用被保留了。因此要有这种行为:
然后,使子组件,即 CompB 重新渲染,好像 angular 以常规方式检测到变化。
您不必特别做任何事情,因为您仍然会在 DOM 中进行更新。
手动变更检测
您可以插入一个更改检测器并像这样触发它:
@Component(
selector: 'compA',
template: template: `<compB [item]=item></compB>`
)
export class CompA
item:any;
constructor(cd: ChangeDetectorRef)
updateItem():void
item[name] = "updated name";
this.cd.detectChanges();
这会触发当前组件及其所有子组件的更改检测。
但是,它不会对您的情况产生任何影响,因为即使 Angular 没有检测到 item
的变化,它 仍然会为孩子运行变化检测 B
组件并更新 DOM。
除非您使用ChangeDetectionStrategy.OnPush
。在这种情况下,一种适合您的方法是手动检查 CompB
的 ngDoCheck
钩子:
import ChangeDetectorRef from '@angular/core';
export class CompB implements OnInit
@Input() item: any;
someArray: any[];
previous;
constructor(cd: ChangeDetectorRef)
ngOnInit():void
this.previous = this.item.name;
someArray.push("something");
ngDoCheck()
if (this.previous !== this.item.name)
this.cd.detectChanges();
您可以在以下文章中找到更多信息:
Everything you need to know about change detection in Angular文章。 The mechanics of DOM updates in Angular The mechanics of property bindings update in Angular【讨论】:
您好,我已经尝试过您的示例代码,但是 ngDoCheck() 方法在应用程序中执行了多次,您能解释一下如何克服这个问题 不确定,但我想您还需要changeDetection: ChangeDetectionStrategy.OnPush
或脱离变更检测?【参考方案2】:
您可以在 CompB 中放置另一个输入,因此当您想要更改 CompA 中项目的属性时,只需更改此输入的值。
@Component(
selector: 'compA',
template: template: `<compB [item]=item [trigger]=trigger></compB>`
)
export class CompA
item:any;
trigger: any;
updateItem():void
item[name] = "updated name";
trigger = new Object();
@Component(
selector: 'compB',
template: template: `<p>item[name]</p>`
)
export class CompB implements OnInit
@Input() item: any;
@Input() trigger: any;
【讨论】:
以上是关于如何手动触发更改事件 - angular2的主要内容,如果未能解决你的问题,请参考以下文章