如何手动触发变更事件-angular2 [英] How to trigger a change event manually - angular2
问题描述
给出以下组件:
@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
)重新渲染,就好像角度检测到常规方式已发生变化一样.
As far as I understood that unless the complete item
object is changed, angular2 does not recognize the changes on item
. Therefore, I'd like to emit a change event manually for item
when the updateItem
method is called. And afterwards, make the child component i.e. CompB
re-rendered as if angular detected a change in the regular way.
当前,我要做的是实现CompB
的ngOnInit
方法,并通过ViewChild
链接在updateItem
方法内部调用该方法.故事的另一部分是,我的实际来源中有someArray
之类的对象,我希望在每个渲染中将其重置.我不确定重新渲染重置someArray
.目前,我正在使用ngOnInit
方法重置它们.
Currently, what I have done is to implement the ngOnInit
method of for CompB
and call that method inside updateItem
method through a ViewChild
link. Another part of the story is that my actual source has objects like someArray
which I'd like to be reset in each render. I'm not sure re-rendering resets someArray
though. Currently, I'm resetting them in the ngOnInit
method.
所以,我的问题是:如何触发父对象更深元素上的更改的重新渲染?
So, my question is: how do I trigger re-rendering for changes on deeper elements of a parent object?
谢谢
推荐答案
据我了解,除非完整的项目对象是 更改,angular2无法识别项目上的更改.
As far as I understood that unless the complete item object is changed, angular2 does not recognize the changes on item.
这不是那么简单.您必须区分在对象发生突变时触发ngOnChanges
和子组件的DOM更新. Angular无法识别item
被更改并且不会触发ngOnChanges
生命周期挂钩,但是如果您在模板中引用item
的特定属性,则DOM仍将更新.这是因为保留了对对象的引用.因此要具有以下行为:
It's not all that straightforward. You have to distinguish between triggering ngOnChanges
when object is mutated and DOM update of the child component. Angular doesn't recognize that item
is changed and doesn't trigger a ngOnChanges
lifecycle hook, but the DOM will still be updated if you reference particular property of the item
in the template. It's because the reference to the object is preserved. Therefore to have this behavior:
然后,使子组件(即CompB)重新呈现,就像 角度检测到规律的变化.
And afterwards, make the child component i.e. CompB re-rendered as if angular detected a change in the regular way.
您不需要做任何特别的事情,因为您仍然可以在DOM中进行更新.
You don't have to do anything in particular because you will still have update in the DOM.
您可以插入一个变更检测器并像这样触发它:
You can insert a change detector and trigger it like this:
@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();
}
}
这将触发对当前组件及其所有子组件的更改检测.
This triggers change detection for the current component and all its children.
但是,它对您的情况没有任何作用,因为即使Angular在item
中未检测到更改,它仍然为孩子运行更改检测 B
组件并更新DOM .
But, it won't have any effect in your case because even though Angular doesn't detect change in item
it still runs change detection for the child B
component and updates the DOM.
除非,否则您使用ChangeDetectionStrategy.OnPush
.在这种情况下,适合您的方法是在CompB
的ngDoCheck
钩子中进行手动检查:
Unless you use ChangeDetectionStrategy.OnPush
. In this case a way to go for you would be to do a manual check in the ngDoCheck
hook of the CompB
:
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();
}
}
}
您可以在以下文章中找到更多信息:
You can find more information in the following articles:
- Everything you need to know about change detection in Angular article.
- The mechanics of DOM updates in Angular
- The mechanics of property bindings update in Angular
这篇关于如何手动触发变更事件-angular2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!