只有来自 *ngIf 指令的第一个匹配 returns ExpressionChangedAfterItHasBeenCheckedError

Only first match from *ngIf directive returns ExpressionChangedAfterItHasBeenCheckedError

我在 ngfor 中有一个嵌套的 ngif:

<ion-content>
    <ng-container *ngFor="let item of (results | async)">
      <ng-container *ngFor="let elements of item.bc; first as isFirst; index as i">
        <ng-container *ngIf="elements.Event.StartTime >= '2019-12-11T15:00:00' ?func():false">
          <ion-item>{{elements.Event.StartTime | date:'shortTime'}}</ion-item>
        </ng-container>
      </ng-container>
    </ng-container>
</ion-content>

我从这里看到了带有函数的分辨率:

export class Tab4Page implements OnInit {

  results: Observable<any>;
  isFirstMatch = false;

  constructor(private channel: Service) {
  }

func() {
    if (this.isFirstMatch === false) {
      this.isFirstMatch = true;
      return true;
    } else {
      return false;
    }
  }

  ngOnInit() {

    this.results = this.channel.searchData();
  }

}

但这对我不起作用。我收到此错误:

ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:'ngIf: true'。当前值:'ngIf: false'.

有没有更好的方法只输出第一个匹配项?或者,如果没有,您能否告诉我应该如何修复 ExpressionChanged 错误。

您可以检查您的 ts 中的第一次出现:

html

<ion-content>
    <ng-container *ngFor="let item of (results | async)">
      <ng-container *ngIf="findFirstElement(item.bc) as element">
          <ion-item>{{element.Event.StartTime | date:'shortTime'}}</ion-item>
        </ng-container>
    </ng-container>
</ion-content>

ts

  findFirstElement(item : any[]){
    if (!this.isFirstMatch && item.some(el => el.Event.StartTime >= '2019-12-11T15:00:00')){
      this.isFirstMatch = true ;
      return item.find(el => el.Event.StartTime >= '2019-12-11T15:00:00') ;
    }

    return null ;
  }

更新

我认为不再需要 isFirstMatch 标志,因为您想为每次迭代(项目)呈现第一次出现:

  findFirstElement(item : any[]){
      return item.find(el => el.Event.StartTime >= '2019-12-11T15:00:00') ;
  }

只需在代码中执行即可:

this.firstMatches$ = this.results.pipe(
  map(results => // rx map operator
    results.map(item => // array map operator to transform
      item.bc.find(el => // into first found match
        el.Event.StartTime >= '2019-12-11T15:00:00')))
);


<ion-content>
  <ng-container *ngFor="let item of (firstMatches$ | async)">
    <ion-item>{{item.Event.StartTime | date:'shortTime'}}</ion-item>
  </ng-container>
</ion-content>

或:

this.firstMatch$ = this.results.pipe(
  map(results => // rx map operator
    results.find(item => // find first item
      !!item.bc.find(el => // that contains a match
        el.Event.StartTime >= '2019-12-11T15:00:00'))),
  map(item => item.bc.find(el => el.Event.StartTime >= '2019-12-11T15:00:00')) // map into that element
);


<ion-content>
  <ng-container *ngIf="firstMatch$ | async as item">
    <ion-item>{{item.Event.StartTime | date:'shortTime'}}</ion-item>
  </ng-container>
</ion-content>

代码比模板强大很多,用吧

模板难以阅读和理解。我不清楚你是想只显示一个 ion-item (对于所有项目中的第一个匹配元素)还是多个(对于每个项目中的第一个匹配元素)。显示了两个答案。