Javascript 角度2:ngOnChanges在模板渲染时激发

Javascript 角度2:ngOnChanges在模板渲染时激发,javascript,angular,typescript,Javascript,Angular,Typescript,当我的模板呈现ngOnChanges中的函数时,仅当@input发生更改时,ngOnChanges才会触发一次。这是预期的行为吗?我如何预防 儿童: export class MobileMenuComponent implements OnInit, OnChanges { @Input('test') dezeTest: string; //declare menu menu; constructor() { //define menu this.menu = {

当我的模板呈现ngOnChanges中的函数时,仅当@input发生更改时,ngOnChanges才会触发一次。这是预期的行为吗?我如何预防

儿童:

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();


}
}

这是ngOnChanges的正常行为

ngOnChanges方法将在第一次激发,因为您的属性已被检查,然后在更新属性时激发。从地图上,你可以看到

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

如果你想改变它,你需要考虑如何改变它。这一点从您的问题中不太清楚,但是如果您想防止NGON更改再次启动,当属性被更新时(我认为您希望这是因为您的代码> ToGLMeNEUE())/代码>,您可以考虑使用<代码> NGunIn()/<代码>而不是<代码> nGangSeunes()/ToC>。;第一次之后

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

或者,正如前面所暗示的,另一个可能更适合您的需要。

这是ngOnChanges的正常行为

ngOnChanges方法将在第一次激发,因为您的属性已被检查,然后在更新属性时激发。从中,您可以看到

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

如果你想改变它,你需要考虑如何改变它。从你的问题来看,这不是很清楚,但是如果你想防止NGON改变再次被触发,当一个属性被更新(我认为你想要这个因为你的代码> ToGelMeMue())/代码>你可以考虑使用<代码> nGunIn()。而不是

ngochanges()
。或者,您可以在第一次之后阻止切换菜单()

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

或者,正如前面所暗示的,另一个可能更适合你的需要。

正如迪伦·米厄斯所建议的,这是正常的行为。 但我建议使用另一种解决方案,它利用传递的SimpleChange对象。它包含previousValue和currentValue。最初,previousValue未设置。


此外,要注意OnChanges,因为它会在每个输入参数上触发…(将来可能会添加更多)

正如Dylan Meeus所建议的,这是正常的行为。 但我建议使用另一种解决方案,它利用传递的SimpleChange对象。它包含previousValue和currentValue。最初,previousValue未设置。


此外,请注意OnChanges,因为它会在每个输入参数上触发…(以后可能会添加更多)

以扩展现有答案,同时解决注释中提出的键入问题:

对于这种情况,存在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:SimpleChange})的“myField”会将不会更新。这可能会导致一些有趣的组件初始化错误。

要扩展现有答案,并同时解决评论中提出的键入问题,请执行以下操作:

对于这种情况,存在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:SimpleChange})的“myField”会将不会更新。这可能会导致一些有趣的组件初始化错误。

谢谢,第二个是我一直在寻找的东西。这个问题背后的故事是,用户应该在一个组件中按下一个按钮,而子组件中需要发生一些事情。有没有更好的方法在不进行ngOnChanges的情况下完成此操作?@Dirk You can's u您可以在某处创建一个保存菜单状态的主题(布尔值的主题,真/假)。当按下组件上的按钮时,更改主题的状态。这将创建一个订阅者可以观察到的事件。(在您的孩子身上,您可以观察到这个事件,并适当地处理更改)好的。这有点像一个带有observable的HTTP请求。您有什么我可以观看或阅读的内容来了解更多关于这个问题的信息吗?因为听起来observable是一个更干净的解决方案。@Dirk看一下这里:这应该对您有所帮助:-)谢谢。这就是我不这么做的原因吗?让that=This;
let menubutton=document.getElementById('menubutton')让clicks=Observable.fromEvent(menubutton,'click')clicks.subscribe(click=>{that.togglemenu();})
谢谢,第二个是我一直在寻找的东西。这个问题背后的故事是,用户应该在一个组件中按下按钮,而子组件中需要发生一些事情。没有ngOnChanges,有没有更好的方法来做到这一点?@Dirk你也可以使用被动扩展。你可以在某个地方创建一个主题它保存菜单的状态(布尔值的主题,真/假)。当按下组件上的按钮时,更改主题的状态。这将创建订阅者可以观察的事件。(在您的孩子中,您可以观察此事件,并适当地处理更改)好的。这有点像一个带有可观察的HTTP请求。你有什么我可以看或读的东西来了解更多关于这个问题的信息吗?因为它是