угловой 6 фильтрует результаты асинхронной трубы - PullRequest
0 голосов
/ 07 ноября 2018

Я использую Angular 6, и я хотел бы отфильтровать результаты асинхронного канала, прежде чем отображать их в пользовательском интерфейсе.

Вот мой код прямо сейчас

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) 
);

и шаблон

  <div *ngIf='results | async ; let items'>
       <div *ngFor='let item of items'>{{item.id}} {{item.name}} </div>               
  </div> 

Из трубы я получаю некоторые идентификаторы и имена. У меня уже есть массив идентификаторов. Я хотел бы фильтровать идентификаторы канала, а не отображать те, которые уже есть в массиве.

Итак, вот что я пытаюсь сделать.

array = [{id:1,name:'one'},{id:2,name:'two'}];//I already have this

новая версия фильтра в трубе

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) ,
  filter(checkIfResultIdInArray())//pseudocode
);

Предположим, что checkIfResultIdInArray - это функция, которую я создал. Фильтрует и возвращает все идентификаторы, которых нет в array. Таким образом, идентификаторы / имена, которые заканчиваются в шаблоне, не являются {id:1,name:'one'},{id:2,name:'two'}.

А может я как-то отфильтрую в шаблоне?

Ответы [ 3 ]

0 голосов
/ 07 ноября 2018

Я думаю, это то, что вы пытаетесь сделать:

this.results = this.form.get('name').valueChanges.pipe(           
  filter(formdata => formdata.name.length > 0), 
  switchMap( formdata => this.service.getNames(formdata.name)) ,
  map(names => names.filter(n => checkIfResultIdInArray(n)))
);

Как правило, в такой конфигурации я бы также добавил оператор debounceTime, чтобы предотвратить слишком много запросов.

0 голосов
/ 07 ноября 2018

@ Ответ Дэви - это то, что я бы сделал сам. Однако другой вариант - использовать трубу. Это путь, если вы хотите использовать эту функцию повторно.

@Pipe({name:'filterOnId'})
export class FilterOnIdPipe implements PipeTransform {
    transform(list : MyObject[], acceptedIds : number[]){
        return list.filter(item => acceptedIds.indexOf(item.id) > -1);
    }
}

и в шаблоне

<div *ngFor='let item of results | async | filterOnId : acceptedIds'>
    {{item.id}} {{item.name}} 
</div>
0 голосов
/ 07 ноября 2018

Как предлагается в комментариях, вы можете заменить AsyncPipe обычным массивом или изменить значение переданного значения (решение @ Davy's хорошо).

Однако существует решение на основе шаблонов. Я помещаю это здесь для тех, кто не хочет объединять логику компонента с отображением представления.

компонент

result$ = of([1,2,3,4,5,6,7,8]); // for the sake of example

isAcceptedThing(thing){
  return thing%2 != 0 // accept only odd numbers
}

шаблон

<ul >
  <ng-container *ngFor="let thing of result$ | async">
    <li *ngIf="isAcceptedThing(thing)">
      filtered thing = {{ thing }} 
    </li>
  </ng-container>
</ul>

выход

  • фильтрованная вещь = 1
  • фильтрованная вещь = 3
  • фильтрованная вещь = 5
  • фильтрованная вещь = 7
...