Javascript Angular 4 过滤器搜索自定义管道

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46780843/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 03:37:24  来源:igfitidea点击:

Angular 4 Filter Search Custom Pipe

javascriptangulartypescriptangular-pipe

提问by T. Evans

So I am trying to build a custom pipe to do a search filter of multiple values in a ngFor loop. I have looked for a number of hours for a good working example, and most of them are based on previous builds and don't seem to work. So I was building the Pipe and using the console to give me the values. However, I cannot seem to get the input text to show up.

所以我试图构建一个自定义管道来在 ngFor 循环中执行多个值的搜索过滤器。我已经花了很多时间寻找一个很好的工作示例,其中大部分都是基于以前的构建并且似乎不起作用。所以我正在构建管道并使用控制台为我提供值。但是,我似乎无法显示输入文本。

Here are the previous places I have looked to find working examples:

以下是我以前寻找工作示例的地方:

Angular 4 Pipe Filter

角 4 管过滤器

http://jilles.me/ng-filter-in-angular2-pipes/

http://jiles.me/ng-filter-in-angular2-pipes/

https://mytechnetknowhows.wordpress.com/2017/02/18/angular-2-pipes-passing-multiple-filters-to-pipes/

https://mytechnetknowhows.wordpress.com/2017/02/18/angular-2-pipes-passing-multiple-filters-to-pipes/

https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview

https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview

https://www.youtube.com/results?search_query=filter+search+angular+2

https://www.youtube.com/results?search_query=filter+search+angular+2

https://www.youtube.com/watch?v=UgMhQpkjCFg

https://www.youtube.com/watch?v=UgMhQpkjCFg

Here is the code that I currently have:

这是我目前拥有的代码:

component.html

组件.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

管道.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());
    });
  }
}

I have imported the pipe into the module.

我已将管道导入模块。

I am still a little newer to Angular 4 and am trying to figure out how to make this work. Anyways thanks for your help!

我对 Angular 4 还是比较新的,并且正在尝试弄清楚如何使这项工作有效。无论如何感谢您的帮助!

I guess I will need to be more specific. I already built out a filter search in JS that does not filter all of the options, which is what I am trying to do. Not just filter the User Name. I am filtering all 4 pieces of data. I chose a Pipe as this was what Angular suggests you do as they originally used them in AngularJS. I am just trying to essentially recreate the filter pipe we had in AngularJS that they removed for performance. All options I have found don't work, or are from previous builds of Angular.

我想我需要更具体。我已经在 J​​S 中构建了一个过滤器搜索,它不会过滤所有选项,这就是我想要做的。不仅仅是过滤用户名。我正在过滤所有 4 条数据。我选择了 Pipe,因为这是 Angular 建议你做的,因为他们最初在 AngularJS 中使用它们。我只是想从根本上重新创建我们在 AngularJS 中的过滤器管道,他们为了性能而删除了它们。我发现的所有选项都不起作用,或者来自以前的 Angular 版本。

If you need anything else from my code let me know.

如果您需要我的代码中的任何其他内容,请告诉我。

回答by chintan kotadiya

I have to implement search functionality in my local and Here is Updated your code. please do this way.

我必须在本地实现搜索功能,这里更新了您的代码。请这样做。

Here is the code that I have to update.

这是我必须更新的代码。

directory Structure

目录结构

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

command run for creating pipe

命令运行以创建管道

ng g pipe search

component.html

组件.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

组件.js

Note: In this file, i have to use dummy records for implementation and testing purpose.

注意:在这个文件中,我必须使用虚拟记录来实现和测试目的。

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

模块.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

管道.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);
        });
    }
}

I hope you are getting the pipe functionality and this will help you.

我希望您获得管道功能,这将对您有所帮助。

回答by Madhavi Gandu

Follow this code to filter specific column instead of all columns in table using custom filters

按照此代码使用自定义过滤器过滤特定列而不是表中的所有列

filename.component.html

文件名.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

文件名.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
Create a class and implement it with PipeTransform, in that way we can write custom filter with transformmethod.

filename.pipe.ts
创建一个类并使用PipeTransform实现它,这样我们就可以使用transform方法编写自定义过滤器。

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
   );
  }
}

回答by Virendra Pandey

Simple filterPipe for Angular 2+

用于 Angular 的简单 filterPipe 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());
        });
   }
}

Here is the HTML

这是 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>

in HTML PropNameis dummy text. In place of PropNameuse your any object property key.

在 HTML PropName 中是虚拟文本。代替PropName使用您的 any 对象属性键。

回答by Prashant M Bhavsar

Here is simple explanation to create custom pipe..as available pipes does not support it. I found this solution here..Nicely explained it

这是创建自定义管道的简单说明。因为可用管道不支持它。我在这里找到了这个解决方案..很好地解释了它

Create pipe file advanced-filter.pipe

创建管道文件 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;
    });

  }

}

Here, array – will be data array passed to your custom pipe obj – will be the object of data by using that object you can add condition to filter data

在这里,数组 – 将是传递给您的自定义管道 obj 的数据数组 – 将是数据的对象,您可以使用该对象添加条件来过滤数据

We have added condition obj.status === args[0]so that data will get filter on status which is passed in .html file

我们添加了条件,obj.status === args[0]以便数据将过滤在 .html 文件中传递的状态

Now, import and declare custom pipe in module.ts file of component:

现在,在组件的 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}]

})

Use of created custom angular pipe in .html file

在 .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>

回答by Sen

A simple Java-like logic that I could think of which might not look very compact in terms of typescript, is as below:

我能想到的一个简单的类 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>

回答by Rahul Gupta

You can use the given function instead on the (input) event of your input box

您可以在输入框的 (input) 事件上使用给定的函数

filterNames(event)
{
 this.names_list = this.names_list.filter(function(tag) {
 return tag.name.toLowerCase().indexOf(event.target.value.toLowerCase()) >= 0;
 });
}

Hope it helps..

希望能帮助到你..