Показать список в зависимости от результатов поиска угловой - PullRequest
0 голосов
/ 26 мая 2018

Я основал это на Поиске героев из туров по туру героев.Там вы можете найти героев, которые возвращают список , который показывает только результаты, содержащие буквы, и позволяет вам щелкнуть по нужному герою.

Я хочу изменить это так, чтобы мой текущий список был отфильтрован по тому, что было введено в поле поиска.

Это то, что вы видите на картинке:

<h1><span id="monstersTitle">Monsters</span></h1>
<app-monster-search></app-monster-search>
<ul class="monsters">
 <li *ngFor="let monster of monsters">
  <span class="badge" (click)="addToEncounter(monster)">{{monster.name}} 
  </span> Hitpoints: {{monster.hitPoints}} Armor: {{monster.armor}}
 </li>
</ul>

И я попытался переместить его в компонент app-monster-search:

<div id="search-component">
<h4>Monster Search</h4>

<input #searchBox id="search-box" (keyup)="search(searchBox.value)" />
<ul class="monsters">
 <li *ngFor="let monster of monsters$ | async">">
  <span class="badge" (click)="addToEncounter(monster)">{{monster.name}} 
   </span> Hitpoints: {{monster.hitPoints}} Armor: {{monster.armor}}
 </li>
</ul>

export class MonsterSearchComponent implements OnInit {
monsters$: Observable<Monster[]>;
private searchTerms = new Subject<string>();

constructor(private monsterService: MonsterService, private sharedService: 
SharedMonsterService) {}

// Push a search term into the observable stream.
search(term: string): void {
 this.searchTerms.next(term);
}

getMonsters(): void{
 this.monsterService.getMonsters()
  .subscribe(monster => this.monsters$ = monster); //error on "this.monsters$" = Type 'Monster[]' is not assignable to type 'Observable<Monster[]>
}

addToEncounter(monster){
 this.sharedService.publishMonster(monster);
}

Проблема здесь в том, что this.monsters $ имеет тип Observable, и мне нужен типмонстр там, чтобы иметь возможность подписаться.Или есть другой / более простой способ добиться этого?

Служба монстров:

public getMonsters(): Observable<Monster[]>{
return this.http.get<Monster[]>(this.monsterUrl).pipe(
  tap(heroes => this.log(`fetched heroes`)),
  catchError(this.handleError('getHeroes', []))
);
}

searchMonsters(term: string): Observable<Monster[]> {
if (!term.trim()) {
  // if not search term, return empty hero array.
  return of([]);
}
return this.http.get<Monster[]>(`${this.monsterUrl}/?name=${term}`).pipe(
  tap(_ => this.log(`found monsters matching "${term}"`)),
  catchError(this.handleError<Monster[]>('searchMonsters', []))
);

} ​​

Редактировать:

Для дальнейшего использования, если другие ищут что-то похожее:

<div id="search-component">
<h4>Monster Search</h4>

<input #searchBox id="search-box" (keyup)="search(searchBox.value)"/>
<ul class="monsters">
<li *ngFor="let monster of (monsters$ | async)">
  <span class="badge" (click)="addToEncounter(monster)">{{monster.name}} 
 </span> Hitpoints: {{monster.hitPoints}}
  Armor: {{monster.armor}}
 </li>
 </ul>
 </div>
<div *ngIf="!searchBox.value">
 <ul class="monsters">
 <li *ngFor="let monster of (monsters)">
  <span class="badge" (click)="addToEncounter(monster)">{{monster.name}} 
  </span> Hitpoints: {{monster.hitPoints}}
  Armor: {{monster.armor}}
 </li>
 </ul>
</div>

Ответы [ 3 ]

0 голосов
/ 26 мая 2018

Таким образом, если у вас есть один список с монстрами, вероятно, загруженный один раз при инициализации компонента, вам не нужен наблюдаемый поток для монстров, потому что этот список не изменяется при вводе чего-либо.Только асинхронная вещь здесь - это пользовательский ввод, и для этого вы можете создать новый поток:

this.filtredMonsters$ = this.searchTerms.pipe(
  map(searchTerms => this.monsters.filter(monster => monster.name.startsWith(searchTerms)))

, а затем изменить цикл ngFor, чтобы использовать filredMonsters $:

<li *ngFor="let monster of filtredMonsters$ | async">

Но помните, чтобы создать этот потоктолько когда доступен список монстров.

0 голосов
/ 26 мая 2018

и если у вашего MonsterService есть метод searchMonsters, вы также можете использовать его, чтобы получить FilterredMonsters $, но замените оператор карты на switchMap:

this.filtredMonsters$ = this.searchTerms.pipe(
  switchMap(searchTerms => this.monsterService.searchMonsters(searchTerms)));
0 голосов
/ 26 мая 2018

Ошибка сама по себе очевидна, просто измените метод " getMonsters () ", как показано ниже: -

getMonsters(): void{
 this.monsters$ = this.monsterService.getMonsters();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...