如何使ng-bootstrap typeahead通过链接显示下拉结果

时间:2019-01-10 04:38:29

标签: bootstrap-4 angular7 ng-bootstrap typeahead

我无法从歌曲服务中获得结果来显示在ng-bootstrap提前输入的结果中。我收到错误消息:“找不到类型为'object'的其他支持对象'[object Object]'。NgFor仅支持绑定到Iterables,例如数组。”

我尝试按照ng-bootstrap网站上的Wikipedia示例进行操作:https://ng-bootstrap.github.io/#/components/typeahead/examples#http

我的.ts文件具有:

formatter = (x: { title: string }) => x.title;

  searchSongTitles = (text$: Observable<string>) =>
text$.pipe(
  debounceTime(800),
  distinctUntilChanged(),
  tap(() => this.loadingNavbarSearchSongs$ = true),
  switchMap(term =>
    this.songsService.getSongsQuickSearch(term, this.titleMatchType$, this.sort$, this.sortDirection$).pipe(
      tap(() => this.loadingNavbarSearchSongsFailed$ = false),
      catchError(() => {
        this.loadingNavbarSearchSongsFailed$ = true;
        return of([]);
      })
    )
  ),
  tap(() => this.loadingNavbarSearchSongs$ = false)
)

我的.html文件具有:

<input id="songtitles-search" placeholder="Song Title" type="text" 
class="form-control form-control-sm my-sm-0 mr-sm-2" 
name="song_titles_search" [(ngModel)]="songTitlesSearchText$" 
[ngbTypeahead]="searchSongTitles" [resultFormatter]="formatter" 
[inputFormatter]="formatter">

模型: songsService.getSongsQuickSearch返回一个     Observable<Song[]> Song具有以下属性:     身份证号码;     标题:字符串;

我需要获取来自getSongsQuickSearch方法的歌曲数组,以便它们是下拉列表中可单击的歌曲标题链接,这些链接基于ID链接到歌曲详细信息页面。例如:

<a [routerLink]="['/song-details', song.id]">{{ song.title }}</a>

2 个答案:

答案 0 :(得分:0)

我最终使用了带有自定义响应视图的ng-bootstrap typeahead。这是使用Angular“ ^ 7.0.1”和“ bootstrap”:“ ^ 4.1.3”和@ ng-bootstrap / ng-bootstrap“:” ^ 3.3.1“

这是我用来使搜索结果显示在搜索输入下的自定义CSS:

#search-results {
    position: absolute;
    width: 160px; /*How wide the results are*/
    background: white;
    border-bottom-left-radius: 10px;
    border-bottom-right-radius: 10px;
    max-height: 500px; /* How far down the results will show */
    overflow-y: auto; /* Show scrollbar if results overflow vertically */
    overflow-x: none; /* Do not show scrollbar horizontally if results overflow */
    border: 1px solid gray;
    left: 150px; /*Where from the left side of the screen the results container starts*/
    right: 0;
    top: 44px; /*Make the results container show under search input*/
}

以下是搜索视图:

<form class="form-inline">
    <input id="songtitles-search" placeholder="Song Title" type="text" class="navbar- 
    search form-control form-control-sm my-sm-0 mr-sm-2" name="song_titles_search" 
    [(ngModel)]="songTitlesSearchText$" [ngbTypeahead]="searchSongTitles">
    <ul id="search-results" class="list-group">
        <li *ngIf="loadingNavbarSearchSongs$" class="list-group-item">
            <img class="small-image" style="width:8em; height:8em;" 
            src="assets/img/loading.gif" />
        </li>
        <li *ngFor="let song of songs$" class="list-group-item">
            <a (click)="songSearchResultChosen()" [routerLink]="['/song-details', 
            song.id]">{{ song.title }}</a> - {{song.main_main_artist}}
        </li>
        <li *ngIf="showNoSearchResultsMessage$">
            <strong>No Song(s) Found Matching Search Criteria</strong>
        </li>
    </ul>
    <button class="btn btn-primary btn-sm my-2 my-sm-0 mr-sm-2" type="submit">
        Search
    </button>
</form>

这是打字稿提前输入代码:

searchSongTitles = (text$: Observable<string>) =>
text$.pipe(
  debounceTime(800),
  distinctUntilChanged(),
  map(term => {
    this.songs$ = [];
    this.showNoSearchResultsMessage$ = false;
    if (term.length > 0) {
      this.songTitlesSearchText$ = term;
      this.getSongs();
    } else {
      this.loadingNavbarSearchSongs$ = false;
    }
  }
  )
)

这是调用我已设置的服务的getSongs方法

getSongs() {
  this.loadingNavbarSearchSongs$ = true;

  this.songsService.getSongsQuickSearch(this.songTitlesSearchText$, this.titleMatchType$,
    this.sort$, this.sortDirection$).subscribe(
    response => {
      this.songs$ = response.songs;
      this.loadingNavbarSearchSongs$ = false;
      if (this.songs$.length <= 0) {
        this.showNoSearchResultsMessage$ = true;
      }
    }
  );
}

您可以在我的网站abovetempo.com的导航栏中看到一个有效的示例 希望这对正在寻找该解决方案的其他人有所帮助!

答案 1 :(得分:0)

另一种方法是使用ng-template。我将其添加为评论,但是我没有足够的声誉。希望它可以帮助其他人寻找相同的解决方案。

https://ng-bootstrap.github.io/#/components/typeahead/examples#template