Angular 2 фильтр/список поиска

Я ищу способ angular 2 this.

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

<md-input placeholder="Item name..." [(ngModel)]="name"></md-input>

<div *ngFor="let item of items">
{{item.name}}
</div>

Каков фактический способ сделать это в angular 2? Это требует трубы?

Ответы

Ответ 1

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

Разметка - HTML-шаблон

<md-input #myInput placeholder="Item name..." [(ngModel)]="name" (input)="filterItem(myInput.value)"></md-input>

<div *ngFor="let item of filteredItems">
   {{item.name}}
</div>

Код

assignCopy(){
   this.filteredItems = Object.assign([], this.items);
}
filterItem(value){
   if(!value){
       this.assignCopy();
   } // when nothing has typed
   this.filteredItems = Object.assign([], this.items).filter(
      item => item.name.toLowerCase().indexOf(value.toLowerCase()) > -1
   )
}
this.assignCopy();//when you fetch collection from server.

Ответ 2

Поиск по нескольким полям

Предполагая данные:

items = [
  {
    id: 1,
    text: 'First item'
  },
  {
    id: 2,
    text: 'Second item'
  },
  {
    id: 3,
    text: 'Third item'
  }
];

Разметка:

<input [(ngModel)]="query">
<div *ngFor="let item of items | search:'id,text':query">{{item.text}}</div>

Труба:

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

@Pipe({
  name: 'search'
})
export class SearchPipe implements PipeTransform {
  public transform(value, keys: string, term: string) {

    if (!term) return value;
    return (value || []).filter(item => keys.split(',').some(key => item.hasOwnProperty(key) && new RegExp(term, 'gi').test(item[key])));

  }
}

Одна строка для всего!

Ответ 3

данные

names = ['Prashobh','Abraham','Anil','Sam','Natasha','Marry','Zian','karan']

Вы можете добиться этого, создав простую трубу

<input type="text" [(ngModel)]="queryString" id="search" placeholder="Search to type">

труба

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

@Pipe({
    name: 'FilterPipe',
})
export class FilterPipe implements PipeTransform {
    transform(value: any, input: string) {
        if (input) {
            input = input.toLowerCase();
            return value.filter(function (el: any) {
                return el.toLowerCase().indexOf(input) > -1;
            })
        }
        return value;
    }
}

Это отфильтрует результат на основе поискового запроса

Больше информации

Ответ 4

В Angular 2 у нас нет предопределенного фильтра и порядка, как это было с AngularJ, нам нужно создать его для наших требований. Время убивать, но нам нужно это сделать (см. No FilterPipe или OrderByPipe). В этой статье мы рассмотрим, как мы можем создать фильтр под названием pipe в angular 2 и функцию сортировки под названием Order By. Давайте использовать простой фиктивный массив данных JSON для него. Вот JSON, который мы будем использовать для нашего примера

Сначала мы увидим, как использовать канал (фильтр) с помощью функции поиска:

Создайте компонент с именем category.component.ts

    import { Component, OnInit } from '@angular/core';
    @Component({
      selector: 'app-category',
      templateUrl: './category.component.html'
    })
    export class CategoryComponent implements OnInit {

      records: Array<any>;
      isDesc: boolean = false;
      column: string = 'CategoryName';
      constructor() { }

      ngOnInit() {
        this.records= [
          { CategoryID: 1,  CategoryName: "Beverages", Description: "Coffees, teas" },
          { CategoryID: 2,  CategoryName: "Condiments", Description: "Sweet and savory sauces" },
          { CategoryID: 3,  CategoryName: "Confections", Description: "Desserts and candies" },
          { CategoryID: 4,  CategoryName: "Cheeses",  Description: "Smetana, Quark and Cheddar Cheese" },
          { CategoryID: 5,  CategoryName: "Grains/Cereals", Description: "Breads, crackers, pasta, and cereal" },
          { CategoryID: 6,  CategoryName: "Beverages", Description: "Beers, and ales" },
          { CategoryID: 7,  CategoryName: "Condiments", Description: "Selishes, spreads, and seasonings" },
          { CategoryID: 8,  CategoryName: "Confections", Description: "Sweet breads" },
          { CategoryID: 9,  CategoryName: "Cheeses",  Description: "Cheese Burger" },
          { CategoryID: 10, CategoryName: "Grains/Cereals", Description: "Breads, crackers, pasta, and cereal" }
         ];
         // this.sort(this.column);
      }
    }
<div class="col-md-12">
  <table class="table table-responsive table-hover">
    <tr>
      <th >Category ID</th>
      <th>Category</th>
      <th>Description</th>
    </tr>
    <tr *ngFor="let item of records">
      <td>{{item.CategoryID}}</td>
      <td>{{item.CategoryName}}</td>
      <td>{{item.Description}}</td>
    </tr>
  </table>
</div>

Ответ 5

HTML

<input [(ngModel)] = "searchTerm" (ngModelChange) = "search()"/>
<div *ngFor = "let item of items">{{item.name}}</div>

компонент

search(): void {
    let term = this.searchTerm;
    this.items = this.itemsCopy.filter(function(tag) {
        return tag.name.indexOf(term) >= 0;
    }); 
}

Обратите внимание, что this.itemsCopy равно this.items и должен быть установлен перед выполнением поиска.

Ответ 6

Вы также можете создать поисковый канал для фильтрации результатов:

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

@Pipe({
  name : 'searchPipe',
})
export class SearchPipe implements PipeTransform {
  public transform(value, key: string, term: string) {
    return value.filter((item) => {
      if (item.hasOwnProperty(key)) {
        if (term) {
          let regExp = new RegExp('\\b' + term, 'gi');
          return regExp.test(item[key]);
        } else {
          return true;
        }
      } else {
        return false;
      }
    });
  }
}

Использовать канал в HTML:

<md-input placeholder="Item name..." [(ngModel)]="search" ></md-input>
<div *ngFor="let item of items | searchPipe:'name':search ">
  {{item.name}}
</div>

Ответ 7

Трубы в Angular 2+ - отличный способ преобразовать и отформатировать данные прямо из ваших шаблонов.

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

Список встроенных каналов из примеровсписка API

{{ user.name | uppercase }}

Пример угловой версии 4.4.7. ng version


Пользовательские трубы, которые принимают несколько аргументов.

HTML « *ngFor="let student of students | jsonFilterBy:[searchText, 'name'] "
TS   « transform(json: any[], args: any[]) : any[] { ... }

Фильтрация содержимого с использованием json-filter-by.pipe.ts " json-filter-by.pipe.ts

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

@Pipe({ name: 'jsonFilterBy' })
@Injectable()
export class JsonFilterByPipe implements PipeTransform {

  transform(json: any[], args: any[]) : any[] {
    var searchText = args[0];
    var jsonKey = args[1];

    // json = undefined, args = (2) [undefined, "name"]
    if(searchText == null || searchText == 'undefined') return json;
    if(jsonKey    == null || jsonKey    == 'undefined') return json;

    // Copy all objects of original array into new Array.
    var returnObjects = json;
    json.forEach( function ( filterObjectEntery ) {

      if( filterObjectEntery.hasOwnProperty( jsonKey ) ) {
        console.log('Search key is available in JSON object.');

        if ( typeof filterObjectEntery[jsonKey] != "undefined" && 
        filterObjectEntery[jsonKey].toLowerCase().indexOf(searchText.toLowerCase()) > -1 ) {
            // object value contains the user provided text.
        } else {
            // object didn't match a filter value so remove it from array via filter
            returnObjects = returnObjects.filter(obj => obj !== filterObjectEntery);
        }
      } else {
        console.log('Search key is not available in JSON object.');
      }

    })
    return returnObjects;
  }
}

Добавить в @NgModule "Добавить JsonFilterByPipe в список объявлений в вашем модуле; если вы забудете это сделать, вы получите сообщение об ошибке без провайдера для jsonFilterBy. Если вы добавите в модуль, он будет доступен для всех компонентов этого модуля.

@NgModule({
  imports: [
    CommonModule,
    RouterModule,
    FormsModule, ReactiveFormsModule,
  ],
  providers: [ StudentDetailsService ],
  declarations: [
    UsersComponent, UserComponent,

    JsonFilterByPipe,
  ],
  exports : [UsersComponent, UserComponent]
})
export class UsersModule {
    // ...
}

Имя файла: users.component.ts и StudentDetailsService создается по этой ссылке.

import { MyStudents } from './../../services/student/my-students';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { StudentDetailsService } from '../../services/student/student-details.service';

@Component({
  selector: 'app-users',
  templateUrl: './users.component.html',
  styleUrls: [ './users.component.css' ],

  providers:[StudentDetailsService]
})
export class UsersComponent implements OnInit, OnDestroy  {

  students: MyStudents[];
  selectedStudent: MyStudents;

  constructor(private studentService: StudentDetailsService) { }

  ngOnInit(): void {
    this.loadAllUsers();
  }
  ngOnDestroy(): void {
    // ONDestroy to prevent memory leaks
  }

  loadAllUsers(): void {
    this.studentService.getStudentsList().then(students => this.students = students);
  }

  onSelect(student: MyStudents): void {
    this.selectedStudent = student;
  }

}

Имя файла: users.component.html

<div>
    <br />
    <div class="form-group">
        <div class="col-md-6" >
            Filter by Name: 
            <input type="text" [(ngModel)]="searchText" 
                   class="form-control" placeholder="Search By Category" />
        </div>
    </div>

    <h2>Present are Students</h2>
    <ul class="students">
    <li *ngFor="let student of students | jsonFilterBy:[searchText, 'name'] " >
        <a *ngIf="student" routerLink="/users/update/{{student.id}}">
            <span class="badge">{{student.id}}</span> {{student.name | uppercase}}
        </a>
    </li>
    </ul>
</div>

Ответ 8

Небольшая модификация ответа @Mosche для обработки, если не существует фильтрующего элемента.

TS:

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

@Pipe({
    name: 'filterFromList'
})
export class FilterPipe implements PipeTransform {
    public transform(value, keys: string, term: string) {

        if (!term) {
            return value
        }
        let res = (value || []).filter((item) => keys.split(',').some(key => item.hasOwnProperty(key) && new RegExp(term, 'gi').test(item[key])));
        return res.length ? res : [-1];

    }
}

Теперь в своем HTML вы можете проверить значение '-1', но безрезультатно.

HTML:

<div *ngFor="let item of list | filterFromList: 'attribute': inputVariableModel">
            <mat-list-item *ngIf="item !== -1">
                <h4 mat-line class="inline-block">
                 {{item}}
                </h4>
            </mat-list-item>
            <mat-list-item *ngIf="item === -1">
                No Matches
            </mat-list-item>
        </div>

Ответ 9

Этот код почти работал для меня... но я хотел многоэлементный фильтр, так что мои моды к трубе фильтра ниже:

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

@Pipe({ name: 'jsonFilterBy' })
@Injectable()
export class JsonFilterByPipe implements PipeTransform {

  transform(json: any[], args: any[]): any[] {
    const searchText = args[0];
    const jsonKey = args[1];
    let jsonKeyArray = [];

    if (searchText == null || searchText === 'undefined') { return json; }

    if (jsonKey.indexOf(',') > 0) {
        jsonKey.split(',').forEach( function(key) {
            jsonKeyArray.push(key.trim());
        });
    } else {
        jsonKeyArray.push(jsonKey.trim());
    }

    if (jsonKeyArray.length === 0) { return json; }

    // Start with new Array and push found objects onto it.
    let returnObjects = [];
    json.forEach( function ( filterObjectEntry ) {

        jsonKeyArray.forEach( function (jsonKeyValue) {
            if ( typeof filterObjectEntry[jsonKeyValue] !== 'undefined' &&
            filterObjectEntry[jsonKeyValue].toLowerCase().indexOf(searchText.toLowerCase()) > -1 ) {
                // object value contains the user provided text.
                returnObjects.push(filterObjectEntry);
                }
            });

    });
    return returnObjects;
  }
} 

Теперь вместо

jsonFilterBy:[ searchText, 'name']

ты можешь сделать

jsonFilterBy:[ searchText, 'name, other, other2...']

Ответ 10

HTML MarkUp:

*ngFor="let item of _items | filtername:{ parametername: searchtext, parametername: searchtext } : false"

Функция преобразования:

transform(items: any, filter: any, isAnd: bool): any {
  if (filter && Array.isArray(items)) {
   let filterKeys = Object.keys(filter);
    if (isAnd) {
     return items.filter(item =>
        filterKeys.reduce((memo, keyName) =>
            (memo && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] === "", true));
    } else {
     return items.filter(item => {
      return filterKeys.some((keyName) => {
        console.log(keyName);
        return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] === "";
      });
    });
   }
  } else {
   return items;
  }
}

Ссылка: https://long2know.com/2017/04/angular-pipes-filtering-on-multiple-keys/