Угловой 4 Фильтр Поиск Custom Pipe
Поэтому я пытаюсь построить пользовательский канал, чтобы сделать фильтр поиска нескольких значений в цикле ngFor. Я искал хороший рабочий пример несколько часов, и большинство из них основаны на предыдущих сборках и, похоже, не работают. Поэтому я строил Pipe и использовал консоль, чтобы дать мне значения. Тем не менее, я не могу получить входящий текст, чтобы показать.
Вот предыдущие места, которые я посмотрел, чтобы найти рабочие примеры:
http://jilles.me/ng-filter-in-angular2-pipes/
https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview
https://www.youtube.com/results?search_query=filter+search+angular+2
https://www.youtube.com/watch?v=UgMhQpkjCFg
Вот код, который у меня сейчас есть:
component.html
<input type="text" class="form-control" placeholder="Search" ngModel="query" id="listSearch" #LockFilter>
<div class="panel panel-default col-xs-12 col-sm-11" *ngFor="let lock of locked | LockFilter: query">
<input type="checkbox" ngModel="lock.checked" (change)="openModal($event, lock)" class="check" id="{{lock.ID}}">
<label for="{{lock.ID}}" class="check-label"></label>
<h3 class="card-text name" ngModel="lock.name">{{lock.User}}</h3>
<h3 class="card-text auth" ngModel="lock.auth">{{lock.AuthID}}</h3>
<h3 class="card-text form" ngModel="lock.form">{{lock.FormName}}</h3>
<h3 class="card-text win" ngModel="lock.win">{{lock.WinHandle}}</h3>
</div>
pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'LockFilter'
})
export class LockFilterPipe implements PipeTransform {
transform(locked: any, query: string): any {
console.log(locked); //this shows in the console
console.log(query); //this does not show anything in the console when typing
if(!query) {
return locked;
}
return locked.filter((lock) => {
return lock.User.toLowerCase().match(query.toLowerCase());
});
}
}
Я импортировал трубу в модуль.
Я все еще немного новичок в Angular 4 и пытаюсь понять, как заставить это работать. В любом случае спасибо за вашу помощь!
Я думаю, мне нужно быть более конкретным. Я уже построил фильтр поиска в JS, который не фильтрует все параметры, что я и пытаюсь сделать. Не просто фильтровать имя пользователя. Я фильтрую все 4 фрагмента данных. Я выбрал трубу, так как это было то, что Angular предлагает вам сделать, так как они изначально использовали их в AngularJS. Я просто пытаюсь воссоздать фильтр, который у нас был в AngularJS, который они удалили для повышения производительности. Все варианты, которые я нашел, не работают или взяты из предыдущих сборок Angular.
Если вам нужно что-то еще из моего кода, дайте мне знать.
3 ответа
Я должен реализовать функцию поиска в моем регионе, и вот обновился ваш код. пожалуйста, сделай так
Вот код, который я должен обновить.
Структура каталога
app/
_pipe/
search/
search.pipe.ts
search.pipe.spec.ts
app/
app.component.css
app.component.html
app.component.ts
app.module.ts
app.component.spec.ts
команда запуска для создания трубы
ng g pipe search
component.html
<input type="text" class="form-control" placeholder="Search" [(ngModel)]="query" id="listSearch">
<div class="panel panel-default col-xs-12 col-sm-11" *ngFor="let lock of locked | LockFilter: query">
<input type="checkbox" (change)="openModal($event, lock)" class="check" id="{{lock.ID}}">
<label [for]="lock.ID" class="check-label"></label>
<h3 class="card-text name">{{lock.User}}</h3>
<h3 class="card-text auth">{{lock.AuthID}}</h3>
<h3 class="card-text form">{{lock.FormName}}</h3>
<h3 class="card-text win">{{lock.WinHandle}}</h3>
</div>
component.js
Примечание. В этом файле я должен использовать фиктивные записи для целей реализации и тестирования.
import { Component, OnInit } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{
public search:any = '';
locked: any[] = [];
constructor(){}
ngOnInit(){
this.locked = [
{ID: 1, User: 'Agustin', AuthID: '68114', FormName: 'Fellman', WinHandle: 'Oak Way'},
{ID: 2, User: 'Alden', AuthID: '98101', FormName: 'Raccoon Run', WinHandle: 'Newsome'},
{ID: 3, User: 'Ramon', AuthID: '28586', FormName: 'Yorkshire Circle', WinHandle: 'Dennis'},
{ID: 4, User: 'Elbert', AuthID: '91775', FormName: 'Lee', WinHandle: 'Middleville Road'},
]
}
}
module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { SearchPipe } from './_pipe/search/search.pipe';
@NgModule({
declarations: [
AppComponent,
SearchPipe
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'LockFilter'
})
export class SearchPipe implements PipeTransform {
transform(value: any, args?: any): any {
if(!value)return null;
if(!args)return value;
args = args.toLowerCase();
return value.filter(function(item){
return JSON.stringify(item).toLowerCase().includes(args);
});
}
}
Я надеюсь, что вы получаете функциональность трубы, и это поможет вам.
Простой фильтрТруба для Angular 2+
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class filterPipe implements PipeTransform {
transform(items: any[], field:string, value: string): any[] {
if(!items) return [];
if(!value) return items;
return items.filter( str => {
return str[field].toLowerCase().includes(value.toLowerCase());
});
}
}
Вот HTML
<input type="text" class="form-control" placeholder="Search" id="listSearch" #search>
<div class="panel panel-default col-xs-12 col-sm-11" *ngFor="let lock of locked | filter:'propName': search.value>
<input type="checkbox" (change)="openModal($event, lock)" class="check" id="{{lock.ID}}">
<label [for]="lock.ID" class="check-label"></label>
<h3 class="card-text name">{{lock.User}}</h3>
<h3 class="card-text auth">{{lock.AuthID}}</h3>
<h3 class="card-text form">{{lock.FormName}}</h3>
<h3 class="card-text win">{{lock.WinHandle}}</h3>
</div>
в HTML PropName является фиктивным текстом. Вместо PropName используйте любой ключ свойства вашего объекта.
Следуйте этому коду, чтобы отфильтровать определенный столбец вместо всех столбцов в таблице с помощью настраиваемых фильтров.
filename.component.html
<table class="table table-striped">
<thead>
<tr>
<th scope="col">product name </th>
<th scope="col">product price</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let respObj of data | filter:searchText">
<td>{{respObj.product_name}}</td>
<td>{{respObj.product_price}}</td>
</tr>
</tbody>
</table>
filename.component.ts
import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-productlist',
templateUrl: './productlist.component.html',
styleUrls: ['./productlist.component.css']
})
export class ProductlistComponent implements OnInit {
searchText: string;
constructor(private http: HttpClient) { }
data: any;
ngOnInit() {
this.http.get(url)
.subscribe(
resp => {
this.data = resp;
}
)
}
}
filename.pipe.ts
Создайте класс и реализуйте его с помощью PipeTransform, чтобы мы могли написать собственный фильтр с помощью метода преобразования.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class PipeList implements PipeTransform {
transform(value: any, args?: any): any {
if(!args)
return value;
return value.filter(
item => item.product_name.toLowerCase().indexOf(args.toLowerCase()) > -1
);
}
}
Вот простое объяснение для создания пользовательского канала... поскольку доступные каналы не поддерживают его. Я нашел это решение здесь.. Красиво объяснил это
Создать файл канала advanced-filter.pipe
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'advancedFilters'
})
export class AdvancedFilterPipe implements PipeTransform {
transform(array: any[], ...args): any {
if (array == null) {
return null;
}
return array.filter(function(obj) {
if (args[1]) {
return obj.status === args[0];
}
return array;
});
}
}
Здесь массив - это массив данных, переданный в ваш пользовательский канал obj - будет объектом данных, используя этот объект, вы можете добавить условие для фильтрации данных
Мы добавили условие obj.status === args[0]
так что данные получат фильтр по статусу, который передается в.html файле
Теперь импортируйте и объявите пользовательский канал в файле module.ts компонента:
import {AdvancedFilterPipe} from './basic-filter.pipe';
//Declare pipe
@NgModule({
imports: [DataTableModule, HttpModule, CommonModule, FormsModule, ChartModule, RouterModule],
declarations: [ DashboardComponent, AdvancedFilterPipe],
exports: [ DashboardComponent ],
providers: [{provide: HighchartsStatic}]
})
Использование созданного пользовательского углового канала в файле.html.
<table class="table table-bordered" [mfData]="data | advancedFilters: status" #mf="mfDataTable" [mfRowsOnPage]="rowsOnPage" [(mfSortBy)]="sortBy" [(mfSortOrder)]="sortOrder">
<thead>
<tr>
<th class="sortable-column" width="12%">
<mfDefaultSorter by="inquiry_originator">Origin</mfDefaultSorter>
</th>
</tr>
</thead>
<tbody class="dashboard-grid">
<ng-container *ngFor="let item of mf.data; let counter = index;">
<tr class="data-row {{ item.status }} grid-panel-class-{{ counter }}">
<td class="align-center">{{ item.trn_date }}</td>
<td>{{ item.trn_ref }}</td>
</tr>
</tbody>
</table>
//If you are using *ngFor and want to use custom angular pipe then below is code
<li *ngFor="let num of (numbers | advancedFilters: status">
{{ num | ordinal }}
</li>
Простая Java-подобная логика, о которой я мог бы подумать, которая может показаться не очень компактной с точки зрения машинописного текста, выглядит следующим образом:
transform(value:IBook[], keyword:string) {
if(!keyword)
return value;
let filteredValues:any=[];
for(let i=0;i<value.length;i++){
if(value[i].name.toLowerCase().includes(keyword.toLowerCase())){
filteredValues.push(value[i]);
}
}
return filteredValues;
}
<h2>Available Books</h2>
<input type="text" [(ngModel)]="bookName"/>
<ul class="books">
<li *ngFor="let book of books | search:bookName"
[class.selected]="book === selectedBook"
(click)="onSelect(book)">
<span class="badge">{{book.name}}</span>
</li>
</ul>
Вы можете использовать данную функцию вместо (входного) события вашего поля ввода
filterNames(event)
{
this.names_list = this.names_list.filter(function(tag) {
return tag.name.toLowerCase().indexOf(event.target.value.toLowerCase()) >= 0;
});
}
Надеюсь, поможет..
Поделиться самым простым решением для поисковой трубы
<input [(ngModel)]="searchText" placeholder="search text goes here">
<ul>
<li *ngFor="let c of studentList | filter : searchText">
{{c.name}}
</li>
</ul>