Как заставить ng-bootstrap typeahead показывать результаты выпадающего меню со ссылкой - PullRequest
0 голосов
/ 10 января 2019

Я не могу получить результаты из своего сервиса песен, чтобы показать в моих результатах ng-bootstrap typeahead. Я получаю сообщение об ошибке: «Не удается найти другой поддерживающий объект« [объект]] типа «объект». NgFor поддерживает только привязку к итерируемым объектам, таким как массивы ».

Я пытался следовать примеру википедии на сайте ng-bootstrap: 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[]> где песня имеет эти свойства: идентификационный номер; название: строка;

Мне нужно взять массив песен, полученных из метода getSongsQuickSearch, чтобы они представляли собой кликабельные ссылки на названия песен в раскрывающемся списке, которые ссылаются на страницу сведений о песне на основе ее идентификатора. Например:

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

1 Ответ

0 голосов
/ 18 января 2019

Я закончил тем, что использовал 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;
      }
    }
  );
}

Рабочий пример можно увидеть в панели навигации на моем веб-сайте вышеtempo.com. Надеюсь, что это поможет кому-то еще, кто ищет это решение!

...