0

我正在使用ng-select自定义服务器端搜索来加载数据,无论用户是否提供了搜索词。

组件.html

<ng-select [items]="filterValues$ | async"
    [typeahead]="filterValuesInput$"
    [multiple]="true"
    (open)="getFilterValues(pref.id)"
    [loading]="filterValuesLoading"
    bindLabel="name"
    [(ngModel)]="filter_values">
</ng-select>

组件.ts

getFilterValues(filterName) {
    this.filterValues$ = concat(
      of([]), // default items
      this.filterValuesInput$.pipe(
        startWith([]),
        distinctUntilChanged(),
        tap(() => this.filterValuesLoading = true),
        switchMap(term => this.preferencesService.getFilterValues(filterName, '' + term).pipe(
          map(res => res.filter_values),
          catchError(() => of([])), // empty list on error
          tap(() => this.filterValuesLoading = false)
        ))
      )
    );
}

我注意到的问题是,每当我打开选择下拉菜单时,它都会触发控制台错误:

Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'loading: false'. Current value: 'loading: true'.

之后,如果提供了搜索词,则由 this.filterValuesLoading 触发的加载微调器可以正常工作。这里有什么问题?谢谢!

4

2 回答 2

0

我设法摆脱了错误。this.filterValuesLoadingthis.filterValuesInput$使用 ngOnInit 生命周期挂钩进行了初始化,但是使用tap(() => this.filterValuesLoading = true)导致了我在第一篇文章中描述的错误。我删除了该行并放在方法this.filterValuesLoading = true的开头getFilterValues()

我愿意接受其他建议,因为我认为这不是最好的方法

于 2020-05-04T05:57:11.183 回答
0

发生这种情况是因为您正在更改filterValues$on open 的值,这不应该是这种情况,您需要定义filterValues$一次,您不需要在每次打开时都这样做,我认为您可以摆脱该功能,并且启动你的filterValues$一次。理想情况下,我会定义一个属性filterValues$并只分配一次值,在此处的 init 示例期间,检查loadPeople在 init 期间调用一次的函数,并且它们根本不使用打开事件发射器。

于 2020-05-02T15:20:40.997 回答