как отфильтровать список, используя трубы в угловых 2 - PullRequest
0 голосов
/ 08 июня 2018

Подскажите, пожалуйста, как отфильтровать список, используя угловые трубы 2

https://stackblitz.com/edit/angular-qvtqeu?file=src%2Fapp%2Fapp.component.html

Я пробовал вот так

<ul class="user-list | filterlist:userenter">
  <li *ngFor="let user of users" class="user-list__item">

Фильтр

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filterlist'
})
export class FilterlistPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    return value.filter(
      item => item.first_name.toLowerCase().indexOf(args.toLowerCase()) > -1
   );
  }

}

Но фильтрация не работает, когда я печатаю в поле ввода?

Ответы [ 5 ]

0 голосов
/ 08 июня 2018

Причина, по которой Angular не поставляется с конвейерами, заключается в том, что он будет иметь ужасную производительность.

Для каждой отдельной строки в вашем массиве вы будете выполнять итерацию всего массива.Повторите это, возможно, несколько раз в секунду.Это не то, что вам нужно.

Вместо этого объявите свой список следующим образом:

allUsers: [];
filteredUsers: [];

Заполните allUsers, как вы в настоящее время делаете users.Затем в каждом месте searchText изменяется, итерация allUsers и добавление соответствующих пользователей в filteredUsers.Таким образом, если только пять пользователей соответствуют вашему тексту поиска, шаблон должен повторяться только пять раз.

Ваш цикл становится:

<ul class="user-list">
  <li *ngFor="let user of filteredUsers" class="user-list__item">
</ul>

И т. Д.

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

0 голосов
/ 08 июня 2018

Вернуть все элементы, если args равно нулю.

import { Pipe, PipeTransform } from '@angular/core';

 @Pipe({
  name: 'filterlist'
 })
 export class FilterlistPipe implements PipeTransform {

 transform(value: any, args?: any): any {
  // added code
  if(args == null){
    return value;
   }
 // added code

   return value.filter(
     item => item.first_name.toLowerCase().indexOf(args.toLowerCase()) > -1
  );
 }

}
0 голосов
/ 08 июня 2018

Вы можете использовать ng2-search-filter npm.
Для получения более подробной информации вы можете просмотреть это демо: Демонстрационная ссылка

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

// search module
import { Ng2SearchPipeModule } from 'ng2-search-filter';

import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, Ng2SearchPipeModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title = 'Angular Search Using ng2-search-filter';
  searchText;
  heroes = [
    { id: 11, name: 'Mr. Nice', country: 'India' },
    { id: 12, name: 'Narco' , country: 'USA'},
    { id: 13, name: 'Bombasto' , country: 'UK'},
    { id: 14, name: 'Celeritas' , country: 'Canada'},
    { id: 15, name: 'Magneta' , country: 'Russia'},
    { id: 16, name: 'RubberMan' , country: 'China'},
    { id: 17, name: 'Dynama' , country: 'Germany'},
    { id: 18, name: 'Dr IQ' , country: 'Hong Kong'},
    { id: 19, name: 'Magma' , country: 'South Africa'},
    { id: 20, name: 'Tornado' , country: 'Sri Lanka'}
  ];
}

app.component.html

<div class="container text-center">
  <h1>{{title}}</h1>
</div>
<div class="container">
  <div class="row">
    <div class="search-hero">
      <input class="form-control" type="text" name="search" [(ngModel)]="searchText" autocomplete="off" placeholder="&#61442;  Start searching for a hero by id or name or country">
    </div>
    <table class="table table-striped">
      <thead>
      <tr>
        <th>Id</th>
        <th>Hero Name</th>
        <th>Country</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let hero of heroes | filter:searchText">
        <td>{{hero.id}}</td>
        <td>{{hero.name}}</td>
        <td>{{hero.country}}</td>
      </tr>
      </tbody>
    </table>
  </div>
</div>

Это позаботится о фильтрации данных из списка результатов.Надеюсь, это поможет вам.

0 голосов
/ 08 июня 2018

Рабочая демоверсия

вы должны сделать вот так

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'filterlist'
})
export class FilterlistPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    if(!args)
     return value;
    return value.filter(
      item => item.first_name.toLowerCase().indexOf(args.toLowerCase()) > -1
   );
  }
}

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

0 голосов
/ 08 июня 2018

Вы применили фильтр к атрибуту class.

Он должен быть в *ngFor:

*ngFor="let user of users | filterlist:userenter"

В вашем коде канала (filterlist.pipe.ts)Возвращает весь массив, когда не установлен фильтр:

if(args === undefined){
  return value;
}
...