Angular 9: 一种形式有多个ngb-typeahead?

Angular 9: More than one ngb-typeahead in one form?

我在我的 Angular 9 应用程序中使用 NgbTypeahead component from NG-Boostrap 6.0.3。第一个很好用,但是我的表格有很多。

是否需要为它们中的每一个添加单独的 ViewChild 和单独的搜索功能?或者我错过了什么?谁能给我举一个不止一个的例子?

作为参考,这里有一个 Stackblitz 只有一个。

好吧,我的评论真的不正确,假设你有 2 个 ngbTypeHead 你需要 focus$ 和 click$ 是一个数组,为此,你可以使用地图,比如

focus$ = [0,1].map(_=>new Subject<string>());
click$ = [0,1].map(_=>new Subject<string>());

好吧,你也可以做一些类似的(我使用傻瓜数组和映射)但它是一样的:

focus$ = [new Subject<string>(),new Subject<string>()];

我对模型使用数组

model: any[]=[];

并更改作为参数接收的searchFunction:一个索引,一个实例和一个术语(索引是引用主题所必需的

searchType(index,instance, text$) {
    return (text$: Observable<string>) => {
      const debouncedText$ = text$.pipe(
        debounceTime(200),
        distinctUntilChanged()
      );
      const clicksWithClosedPopup$ = this.click$[index].pipe(
        filter(() => !instance.isPopupOpen())
      );
      const inputFocus$ = this.focus$[index];

      return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
        map(term =>
          (term === ""
            ? states
            : states.filter(
                v => v.toLowerCase().indexOf(term.toLowerCase()) > -1
              )
          ).slice(0, 10)
        )
      );
    };
  }

然后,我们唯一需要的就是改变我们的 ngbTypeahead

  <input
        ...
  [(ngModel)]="model[index]"
  [ngbTypeahead]="searchType(i,instance,$text)"
  (focus)="focus$[i].next($any($event).target.value)"
  (click)="click$[i].next($any($event).target.value)"
  #instance="ngbTypeahead"
  >

您可以在 stackblitz

中查看示例

Update如果我们需要不同的数据,我们可以通过"data"改进函数搜索,所以,如果我们添加一个新的参数来搜索:

searchType(index,instance, data,text$) { //<--pass "data"
    return (text$: Observable<string>) => {
      const debouncedText$ = text$.pipe(
        debounceTime(200),
        distinctUntilChanged()
      );
      const clicksWithClosedPopup$ = this.click$[index].pipe(
        filter(() => !instance.isPopupOpen())
      );
      const inputFocus$ = this.focus$[index];

      return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
        map(term =>
          (term === ""
            ? data          //<--here use data
            : data.filter(  //<--here use data too
                v => v.toLowerCase().indexOf(term.toLowerCase()) > -1
              )
          ).slice(0, 10)
        )
      );
    };
  }

我们可以改写调用:

[ngbTypeahead]="searchType(i,instance,states,$text)"

另一种方案是,根据"index"在一个或另一个数组中查找,所以函数就变成了像

searchType(index,instance, text$) { 
    const data=index==0?states:this.fruits; //<--the data according the index
    return (text$: Observable<string>) => {
      const debouncedText$ = text$.pipe(
        debounceTime(200),
        distinctUntilChanged()
      );
      const clicksWithClosedPopup$ = this.click$[index].pipe(
        filter(() => !instance.isPopupOpen())
      );
      const inputFocus$ = this.focus$[index];

      return merge(debouncedText$, inputFocus$, clicksWithClosedPopup$).pipe(
        map(term =>
          (term === ""
            ? data          //<--here use data
            : data.filter(  //<--here use data too
                v => v.toLowerCase().indexOf(term.toLowerCase()) > -1
              )
          ).slice(0, 10)
        )
      );
    };
  }