Angular 2:ngOnChanges在模板渲染时触发

时间:2016-08-11 10:02:36

标签: javascript angular typescript

当我的模板呈现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();


}
}

3 个答案:

答案 0 :(得分:4)

这是ngOnChanges的正常行为。

ngOnChanges方法将首次触发,因为您的属性已被检查,并且随后在更新属性时触发。从documentation开始,您可以看到

  

在检查了数据绑定属性之后,在检查了视图和内容子项之前,如果至少有一个子项已更改,则会立即调用ngOnChanges。

如果您想要更改它,您需要考虑如何更改它。从你的问题来看,这不是很清楚,但是如果你想阻止ngOnChanges再次触发,当一个属性被更新时(我认为你想要这个因为你的toggleMenu()而可能会考虑使用ngOnInit()而不是ngOnChanges()。或者,您可以在第一次之后阻止togglemenu();

 firstrun : boolean = true; // class variable
 ngOnChanges(changes : SimpleChanges){
    if(firstrun){
      this.togglemenu();
      firstrun = false;
    }
  }

或者,如前所述,另一个lifecycle hook可能更适合您的需求。

答案 1 :(得分:2)

扩展现有答案,同时解决评论中提出的输入问题:

对于这种确切的情况,存在SimpleChange#firstChange字段。

或者,因为在调用ngOnChanges之前在Component上设置了值,您还可以检查字段是否已更改,然后是否已设置:

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'在你的组件上,' myField'的ngOnChanges方法参数({myField:SimpleChange})将不会更新。这可能会导致一些有趣的组件初始化错误。

答案 2 :(得分:1)

正如Dylan Meeus所说,它的正常行为。 但我会建议一个不同的解决方案,它利用传递的SimpleChange对象。它包含previousValue和currentValue ..最初,未设置previousValue。 https://angular.io/docs/ts/latest/api/core/index/SimpleChange-class.html

ngOnChanges(changes : any){
   if(changes.menu.previousValue){
      this.togglemenu();
   }
}

另外,请注意OnChanges,因为它会触发每个输入参数...(您将来可能会添加更多)