首页 文章

角4管过滤器

提问于
浏览
20

我正在尝试使用自定义管道使用带有ngModel的输入字段来过滤我的 *ngFor 循环 . 使用我的其他自定义管道(sortBy),它工作得很好 . 但是,过滤管似乎使得没有数据出现 . 我还在学习这个,我尝试了一些变化无济于事:

-filter: term
-filter: {{term}}
-filter: 'term'
-filter" {{'term'}}

所以我认为问题可能在于代码中的其他地方 . 如果有人可以提供帮助,我会非常感激 .

这是我的代码:

HTML Component

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
  </h1>

</div>
<h2>Please choose your favorite song: </h2>
<form id="filter">
    <label>Filter people by name:</label>
    <input type="text" name="term" [(ngModel)]="term" />
</form>


<table class="table">
    <thead>
      <tr>
        <th>Title</th>
        <th>Artist</th>
        <th>Likes</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let song of songs | filter:term| sortBy: 'likes'; let i  = index">
        <td>{{song.title}}</td>
        <td>{{song.artist}}</td>
        <td>{{song.likes}} 

            <i class="fa fa-heart-o" aria-hidden="true"  *ngIf="song.likes < 1"></i>
         <i class="fa fa-heart" aria-hidden="true" *ngIf="song.likes >= 1"></i>
             <i class="fa fa-plus" aria-hidden="true" (click)="addLike(i)" ></i>
            <i class="fa fa-minus" aria-hidden="true" (click)="removeLike(i)" ></i>

          </td>
      </tr>
    </tbody>
  </table>

PIPE

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

@Pipe({
    name: 'filter',
    pure: false
})

export class FilterPipe implements PipeTransform {
    transform(items: any[], args: any[]): any {
        return items.filter(item => item.id.indexOf(args[0]) !== -1);
    }
}

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

import { AppComponent } from './app.component';
import { SortByPipe } from './sort-by.pipe';
import { FilterPipe } from './filter.pipe';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Pipe, PipeTransform } from '@angular/core'; 


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

JS组件

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'Oxcord';
  songs = [

  {title: "Song", artist: "Artist", likes: 1},
  {title: "Chanson", artist: "Artiste", likes: 3},
  {title: "ABC", artist: "OneTwoThree", likes: 2},
  {title: "Trash", artist: "Meek Mill", likes: 0}

  ];
  addLike(input){
  this.songs[input].likes +=1;
} 
removeLike(input){
  this.songs[input].likes -=1;
} 
args="Me";
}

3 回答

  • 8

    这是一个带有过滤器和sortBy管道的工作plunkr . https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview

    正如注释中提到的developer033,当过滤器管道期望一组值时,您将一个值传递给过滤器管道 . 我会告诉管道期望单个值而不是数组

    export class FilterPipe implements PipeTransform {
        transform(items: any[], term: string): any {
            // I am unsure what id is here. did you mean title?
            return items.filter(item => item.id.indexOf(term) !== -1);
        }
    }
    

    我同意DeborahK的观点,即出于性能原因应避免使用不纯的管道 . plunkr包含控制台日志,您可以在其中查看不纯管道的调用量 .

  • 1

    变换方法签名在Angular 2的RC中某处发生了变化 . 尝试更像这样的东西:

    export class FilterPipe implements PipeTransform {
        transform(items: any[], filterBy: string): any {
            return items.filter(item => item.id.indexOf(filterBy) !== -1);
        }
    }
    

    如果你想处理空值并使过滤器不敏感,你可能想要做一些更像我在这里的事情:

    export class ProductFilterPipe implements PipeTransform {
    
        transform(value: IProduct[], filterBy: string): IProduct[] {
            filterBy = filterBy ? filterBy.toLocaleLowerCase() : null;
            return filterBy ? value.filter((product: IProduct) =>
                product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value;
        }
    }
    

    注意:管道中的排序和过滤是性能的一个大问题,不建议使用它们 . 有关详细信息,请参阅此处的文档:https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe

  • 19

    Angular 2中的Pipes是直接从模板转换和格式化数据的好方法 .

    管道允许我们更改模板内的数据;即过滤,排序,格式化日期,数字,货币等 . 一个简单的例子是你可以通过在模板代码中应用一个简单的过滤器将字符串转换为小写 .

    内置管道列表来自API List示例

    {{ user.name | uppercase }}
    

    Angular版本4.4.7的示例 . ng version


    Custom Pipes,接受多个参数 .

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

    使用管道过滤内容« 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.tsStudentDetailsService 是从this link创建的 .

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

相关问题