ngOnChanges 多次调用

ngOnChanges is calling up multiple times

我已经使用 ngFor 生成了多个离子载玻片,并在其中插入了一个组件。它多次调用 ngOnChanges。我希望它只调用一次,这样我就可以调用我的 api.

我已经尝试使用多个 angular 生命周期挂钩。

这就是我创建幻灯片的方式,菜单有 19 个元素

<ion-slides #slides [options]="slideOpts" (ionSlideDidChange)="slideChanged($event)">
<ion-slide *ngFor="let i of menu; let j = index">
  <h1>{{ i.name }}</h1>
  <app-homenews [categoryId]="currentCategoryId" ></app-homenews>
</ion-slide>
</ion-slides>

这就是我们进行变化检测的方式

@Input() categoryId: number;

ngOnChanges(changes: SimpleChanges) {
   let chg = changes['categoryId'];
   console.log(chg.currentValue);
} 

我只想调用一次,现在调用了19次。

我可以在这里使用 rxjs 吗?

ngOnChanges 当来自模板的输入变量的值发生变化时运行 binding.So 多次触发它是正常的 behavior.If 你只想执行一次代码可以这样用

@Input() isFirstRun;
ngOnChanges(changes: SimpleChanges) {
  if(this.isFirstRun){
     let chg = changes['categoryId'];
     console.log(chg.currentValue);
  }
}

<ion-slide *ngFor="let i of menu; let j = index">
  <h1>{{ i.name }}</h1>
  <app-homenews [isFirstRun]="j===0?true:false" [categoryId]="currentCategoryId" ></app-homenews>
</ion-slide>

您可以在服务中添加一个 isFirstRun 标志并在您的组件中使用它 您可以继续使用 ngOnchanges,因为它会在值发生变化时提供帮助

ngOnChanges(changes: SimpleChanges) {
if (this.flagService.isFirstRun || value has changed) {
// call API
}
} 

这个方法我用过一次,避免了ngOnChanges循环的使用

在你的组件中:

private _changes;
private id;
@Input()
  set changes(changes) {     

      this._changes= changes;
      this.id = changes[id];

    }
  }
  get changes(): string {
    return this._changes;
  }

虽然其他答案在技术上是正确的,但我觉得最好使用 getter-setter 或您已经传递给生命周期挂钩的 SimpleChanges 对象,而不是 isFirstRun 标志. SimpleChanges 对象包含您已经需要的所有信息。

class SimpleChange {
  constructor(previousValue: any, currentValue: any, firstChange: boolean)
  previousValue: any
  currentValue: any
  firstChange: boolean
  isFirstChange(): boolean
}

在运行时间内,包含one/many个SimpleChanges对象的对象对应于组件的Input变量将被传递到NgOnChanges中,格式如上。像我在下面所做的那样检查 firstChange 值会更容易;

@Input() categoryId: number;

ngOnChanges(changes: SimpleChanges) {
   if(changes['categoryId'].firstChange) {
     let chg = changes['categoryId'];
     console.log(chg.currentValue);
     //other program logic
   }
} 

请注意:如果您将来自 API 响应的数据输入到子组件中,可能会在 API 调用之前 运行 发送空值初始化,并且 firstChange 将针对该输入设置为 true。在那种特殊情况下,检查前一个值是否为 null 以及当前值是否存在应该就足够了。