网站搜索

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 }) 将不会被更新。这可能会导致一些有趣的组件初始化错误。