javascript - Angular 2:当模板渲染时 ngOnChanges 触发
当我的模板渲染函数时,ngOnChanges 内的函数会触发一次,然后只有在 @Input 发生变化时才会触发。这是预期的行为吗,我该如何防止它?
孩子:
export class MobileMenuComponent implements OnInit, OnChanges {
@Input('test') dezeTest: string;
//declare menu
menu;
constructor() {
//define menu
this.menu = {state: 'inactive'};
}
togglemenu() {
var that = this;
if (that.menu.state === 'inactive'){
that.menu.state = 'active';
}
else {
that.menu.state = 'inactive';
}
}
ngOnChanges(changes: SimpleChanges) {
this.togglemenu();
}
}
答案#1
这是 ngOnChanges 的正常行为。
ngOnChanges 方法第一次会触发,因为你的属性已经被检查过,随后当属性被更新时也会触发。从文档中,你可以看到
ngOnChanges 在数据绑定的属性被检查之后、视图和内容子元素被检查之前调用,如果其中至少有一个属性发生了变化。
如果你想要更改它,你需要考虑你想如何更改它。从你的问题来看,这一点不是很清楚,但如果你想在属性更新时防止 ngOnChanges 再次触发(我认为你之所以想要这样是因为你的 toggleMenu()),你可以考虑使用 ngOnInit() 代替 ngOnChanges()。或者,你也可以在第一次之后阻止 toggleMenu(); 的执行。
firstrun : boolean = true; // class variable
ngOnChanges(changes : SimpleChanges){
if(firstrun){
this.togglemenu();
firstrun = false;
}
}
或者,如前所暗示的,另一个生命周期钩子可能更适合你的需求。
答案#2
为了扩展现有的答案,同时回应评论中提出的一个打字问题:
SimpleChange#firstChange 字段正是为这种情况存在的。
或者,因为值在 ngOnChanges 被调用之前已经在你的组件上设置,你也可以先检查字段是否已更改,然后再检查它是否被设置:
ngOnChanges(changes: { myField: SimpleChange }) {
if(changes.myField && this.myField){
// do a thing only when 'myField' changes and is not nullish.
}
// Or, if you prefer:
if(changes.myField && changes.myField.firstChange){
// Do a thing only on the first change of 'myField'.
// WARNING! If you initialize the value within this class
// (e.g. in the constructor) you can get null values for your first change
}
}
另一个小提示:如果你使用像 WebStorm 这样的工具重命名组件上的 'myField',ngOnChanges 方法参数中的 'myField' ({myField: SimpleChange }) 将不会被更新。这可能会导致一些有趣的组件初始化错误。
