输入属性更改时,ngOnChanges停止触发

时间:2018-02-16 05:41:57

标签: angular

我正在使用Angular @Input属性为这样的子组件设置布尔值。我期待每2秒打印一次'Inside ngOnChanges'。但是,我可以看到它只打印两次,然后不会发生更改检测。有人可以建议我如何解决这个问题?

父组件:

@Component({
  selector: 'my-app',
  template: `
    <div>
      <my-app-child [repaint]="triggerRepaint"></my-app-child>
    </div>
  `,
})
export class App implements OnInit {
  triggerRepaint: boolean
  constructor() {

  }

  ngOnInit(){
  setInterval(()=>{
     this.triggerRepaint = false;
     //do something
      this.triggerRepaint = true;
   }, 2000);
  }
}

子组件:

@Component({
  selector: 'my-app-child',
  template: `
    <div>

    </div>
  `
})
export class ChildComponent implements OnChanges {
  @Input() repaint: boolean = false;

  constructor() {

  }

  ngOnChanges(){
     console.log('Inside ngOnChanges');
  }
}

输出: enter image description here

1 个答案:

答案 0 :(得分:1)

这个问题是这两行:

this.triggerRepaint = false;
//do something
this.triggerRepaint = true;
  

原因:每次它都会向子组件发送true,所以它会发送   不被视为改变

将其更改为:

//do something
this.triggerRepaint = !this.triggerRepaint;

setInterval(()=>{
  this.triggerRepaint = false;
  //do something
  setTimeout(()=> {
    this.triggerRepaint = true;
  });
}, 2000);

<强> WORKING DEMO

请仔细阅读以下方案,了解更深入的细节

  

不会调用更改检测,直到执行整个功能,   这里发生的事情是,一旦你调用它进入的功能   执行队列一旦执行此更改检测   将被称为

  

1)在您的情况下

setInterval(()=>{
     this.triggerRepaint = false;
     //do something
     this.triggerRepaint = true;
   }, 2000);
}

队列:

this.triggerRepaint = false;
//do something     
this.triggerRepaint = true;
// change detection will be called -> Here last value will always be same after first execution 

活动池:

Blank
  

2)没有setTimeout

setInterval(()=>{
     this.triggerRepaint = !this.triggerRepaint;
   }, 2000);
}

队列:

this.triggerRepaint = !this.triggerRepaint;
// change detection will be called -> Here last value will always be different from previous one

活动池:

Blank
  

2)使用setTimeout

setInterval(()=>{
  this.triggerRepaint = false;
  //do something
  setTimeout(()=> {
    this.triggerRepaint = true;
  },0);
}, 2000);

队列:

this.triggerRepaint = false;
//do something
// change detection will be called -> last value always be false

事件池:(一旦上面的队列被清除,它将在执行下方推送到队列并执行)

setTimeout
this.triggerRepaint = true;
// change detection will be called -> last value always be false