how to stop ngOnChanges Called before ngOnInit()

后端 未结 3 1779
南方客
南方客 2020-12-13 14:07

In my angular application, i came up with a situation where ngOnchanges should only be called when the inputs are bound to changes. so, is there a way to stop the execution

相关标签:
3条回答
  • 2020-12-13 14:22

    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

    You can also check the SimpleChange.isFirstChange() method :

    isFirstChange() : boolean Check whether the new value is the first value assigned.

    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"
        }
      }
    
    }
    
    0 讨论(0)
  • 2020-12-13 14:30

    In case it helps anyone here's an example of how I implemented the isFirstChange() solution suggested by @n00dl3 into my AngularJS app:

    this.$onChanges = (changes) => {
        if (!changes.value.isFirstChange()) {
            // do stuff
        }
    };
    
    0 讨论(0)
  • 2020-12-13 14:35

    One method I have found that works is based on the fact that the input values all have a previous value property. If the input has not previously been set then that value will be CD_INIT_VALUE (as a string). 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. 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.

    0 讨论(0)
提交回复
热议问题