首页 > 解决方案 > 从 Angular 上的数组中搜索过滤器

问题描述

我有一个存储汽车列表的应用程序。我想将 Search 属性添加到我的项目中。我决定为我的 searchBox 使用 pipe 和 ngModel 来做到这一点。我有一个数组被 subscribe() 监听任何事情都会发生变化。在管道中,我有const obj变量,它根据我希望的组件中的 ngModel 过滤数组。但是角度给出错误并说ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'undefined: [object Object],[object Object],[object Object]'. Current value: 'undefined: '.。我猜一开始它是未定义的,这就是它发生的原因。但是我添加了 if block in为了检查未定义与否,而不是得到这个错误。这是我的组件和下面的管道

汽车列表组件.html

  <form class="example" style="margin:auto;max-width:200px">
    <input [(ngModel)]="nameBrand" type="text" placeholder="Search.." name="search2">
  </form>
  <div class="row">
    <div class="col-xs-12">
      <app-car-item
        *ngFor="let carEl of cars | orderName:nameBrand ;let i = index"
        [car]="carEl"
        [index]="i"
        >
      </app-car-item>
    </div>
  </div>

OrderPipe.ts

@Pipe({
  name: 'orderName',
})
export class OrderNamePipe implements PipeTransform{
  constructor(private carService:CarService)
  {

  }
  transform(value: any, arg1: any) 
   {       
      const obj = this.carService.getCars().filter(s => s.brand.includes(arg1));      
      if(obj)
      {
           this.carService.setCars(obj);
     }
    }
  }

汽车列表.component.ts

  ngOnInit() {
    this.subscription=this.carService.carsChanged
    .subscribe(
     (cars:Car[])=>
     {
       this.cars=cars;
     }
    );
    this.cars = this.carService.getCars();
    }

汽车服务.ts

        export class CarService
    {
       carsChanged=new Subject<Car[]>();
       private cars: Car[]=[
            new Car(
               'Dodge Viper SRT10',
               'Coupe',
               2017,
               645,
               600,
               'Gasoline',
               'Used',
               'http://cdn-ds.com/stock/2010-Dodge-Viper-SRT10-ACR-Ltd-Avail-Akron-OH/seo/ECL2585-1B3AZ6JZ6AV100278/sz_88264/b22eddbbf045c389bd39e4ede1328f13.jpg',
               970000
           ),
           new Car(
            'Chevrolet Camaro',
            'Coupe',
            2012,
            432,
            600,
            'Gasoline',
            'Used',
            'https://carimages.com.au/MdzpzcZ7iNNuMu7RlH3Eg5t30CM=/fit-in/800x540/filters:stretch(FFFFFF)/vehicles/used/2018/CHEVROLET/CAMARO/2018-CHEVROLET-CAMARO-used-78-JWF447-1.jpg',
            274000
        ),
        new Car(
            'Bentley Continental-GT',
            'Coupe',
            2018,
            601,
            489,
            'Gasoline',
            'New',
            'https://cdn1.autoexpress.co.uk/sites/autoexpressuk/files/2017/11/4bentleycontinentalgt.jpg',
            4150000
        ) 
       ]
       constructor()
       {}
       setCars(cars: Car[]) {
        this.cars = cars;
        this.carsChanged.next(this.cars.slice());
 getCars()
   {
    return this.cars;
   }
      }

汽车模型.ts

export class Car{
    public brand:string;
    public type:string;
    public year:number;
    public bhp:number;
    public torque:number;
    public fuel:string;
    public condition:string;
    public imageUrl:string;
    public price:number;

    constructor(brand:string,type:string,year:number,bhp:number,torque:number,fuel:string,condition:string,imageUrl:string,price:number)
    {
        this.brand=brand;
        this.type=type;
        this.year=year;
        this.bhp=bhp;
        this.torque=torque;
        this.fuel=fuel;
        this.condition=condition;
        this.imageUrl=imageUrl;
        this.price=price;
    }
}

标签: javascriptarraysangular

解决方案


我认为这不是使用管道内服务数据的好方法。试试这个管道,

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

@Pipe({
    name: 'orderName'
})

@Injectable()
export class OrderNamePipe implements PipeTransform {
    transform(items: any[], field: string, value: string): any[] {
        if (!items) {
            return [];
        }
        if (!field || !value) {
            return items;
        }
        return items.filter(singleItem => singleItem[field].toLowerCase().includes(value.toLowerCase()));
    }
}

这样,您的管道是可重复使用的。将您的模板更改为,

<app-car-item
    *ngFor="let carEl of cars | orderName : 'brand' : nameBrand ;let i = index"
    [car]="carEl"
    [index]="i"
    >
</app-car-item>

指定了“品牌”,因为您需要根据该字段进行过滤。


推荐阅读