简体   繁体   English

如何停止在 ngOnInit() 之前调用的 ngOnChanges

[英]how to stop ngOnChanges Called before ngOnInit()

In my angular application, i came up with a situation where ngOnchanges should only be called when the inputs are bound to changes.在我的 angular 应用程序中,我想出了一种情况,即只有在输入绑定到更改时才应调用 ngOnchanges。 so, is there a way to stop the execution of ngOnChanges before ngOnInit.那么,有没有办法在 ngOnInit 之前停止 ngOnChanges 的执行。 Is there a way to accomplish this.有没有办法做到这一点。 Thanks in Advance.提前致谢。

You cannot prevent this behavior, but you can:您无法阻止这种行为,但您可以:

Use a Subject :使用主题:

class Foo implements OnChanges,OnInit,OnDestroy{

  onChanges = new Subject<SimpleChanges>();

  ngOnInit(){
    this.onChanges.subscribe((data:SimpleChanges)=>{
      // only when inited
    });
  }
  ngOnDestroy(){
    this.onChanges.complete();
  }

  ngOnChanges(changes:SimpleChanges){
    this.onChanges.next(changes);
  }

}

Use a boolean property:使用布尔属性:

class Foo implements OnChanges,OnInit{

  initialized=false;

  ngOnInit(){
    // do stuff
    this.initialized = true;
  }

  ngOnChanges(changes:SimpleChanges){
    if(this.initialized){
      // do stuff when ngOnInit has been called
    }
  }

}

Use the SimpleChanges API使用SimpleChanges API

You can also check the SimpleChange.isFirstChange() method :您还可以检查SimpleChange.isFirstChange()方法:

isFirstChange() : boolean Check whether the new value is the first value assigned. isFirstChange() : boolean检查新值是否是第一个分配的值。

class Foo implements OnChanges,OnInit{

  @Input()
  bar:any;

  ngOnInit(){
    // do stuff
  }

  ngOnChanges(changes:SimpleChanges){
    if(!changes["bar"].isFirstChange()){
      // do stuff if this is not the initialization of "bar"
    }
  }

}

One method I have found that works is based on the fact that the input values all have a previous value property.我发现一种有效的方法是基于这样一个事实,即输入值都具有先前的 value 属性。 If the input has not previously been set then that value will be CD_INIT_VALUE (as a string).如果之前未设置输入,则该值将为CD_INIT_VALUE (作为字符串)。 So you can make a condition that your block of code in ngOnChanges should only run if the previous value is not CD_INIT_VALUE .因此,您可以设置一个条件,即ngOnChanges的代码块应仅在先前值不是CD_INIT_VALUE Here's an example for your case where you're testing ALL the input values:这是您正在测试所有输入值的情况的示例:

ngOnChanges(changes: SimpleChanges) {
  let initialized: boolean = true;
  for (let prop in changes) {
    if (changes[prop].previousValue.toString() === 'CD_INIT_VALUE') {
      initialized = false;
      //we can break here since if any item is not initialized
      //we will say the inputs are NOT initialized
      break;
    }
  }

  if (initialized) {
    //code you want to execute
  }    
}

There are probably more elegant solutions but I've found this works.可能有更优雅的解决方案,但我发现这有效。 This is probably too late to help you but may help others as when I googled this I found this question.这可能为时已晚,无法帮助您,但可能会帮助其他人,因为当我搜索此问题时,我发现了这个问题。 The solution was something I figured out from debugging.解决方案是我从调试中发现的。

In case it helps anyone here's an example of how I implemented the isFirstChange() solution suggested by @n00dl3 into my AngularJS app:如果它对任何人有帮助,这里有一个示例,说明我如何将 @n00dl3 建议的isFirstChange()解决方案实施到我的 AngularJS 应用程序中:

this.$onChanges = (changes) => {
    if (!changes.value.isFirstChange()) {
        // do stuff
    }
};

I guess this is not what the OP is looking for, but the following provides a way to get rid of the ngOnChanges() call without any modification in your component's code. 我想这不是OP想要的,但是以下内容提供了一种无需对组件代码进行任何修改即可摆脱ngOnChanges()调用的方法。

Instead of declaring your component with the appropriate selector in your template, you could instead have an ng-template: 与其在模板中使用适当的选择器声明组件,不如使用ng-template:

<ng-template></ng-template>

And then spawn your component inside this ng-template using ViewContainerRef#createComponent method. 然后使用ViewContainerRef#createComponent方法在此ng模板中生成组件。

This way, your component will be instantiated without any input and ngOnChanges() won't be called before ngOnInit() anymore. 这样一来,你的组件将在没有任何输入和ngOnChanges()来实例化不会被ngOnInit()之前再调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM