【问题标题】:Search filter from array on Angular从 Angular 上的数组中搜索过滤器
【发布时间】:2019-09-06 06:57:25
【问题描述】:

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

汽车列表组件.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);
     }
    }
  }

Car-list.component.ts

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

Car.Service.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;
   }
      }

Car-Model.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;
    }
}

【问题讨论】:

  • 如果你尝试在你的
  • 你能更新getCars() methodCar[]吗?
  • @federicoscamuzzi 向我抛出了这个错误:ExpressionChangedAfterItHasBeenCheckedError: Expression Changed after it was checked after it has changed.以前的值:'ngIf: 3'。当前值:'ngIf: 0'
  • @piyushjain 我做了
  • 它是 @input() 道具吗?

标签: javascript arrays angular


【解决方案1】:

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

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>

指定了'brand',因为您需要根据该字段进行过滤。

【讨论】:

  • 感谢您的关注。我采用了类似的方法,但这里有一个问题。例如,在搜索任何品牌之前,当您从 URL 中的列表中单击任何汽车时,它会返回 car/1 例如(在图片你可以在搜索后看到i.ibb.co/kKNtFN1/cars-1.jpg).But,如果我在列表中选择(再次在此示例中为 Camaro),则返回 id:0 Dodge Viper (i.ibb.co/XyVfdcn/Cars-2.jpg)。这就是我尝试通过 setCar 更新服务中的汽车的原因() 方法
  • @TimuçinÇiçek 你确定这是一个正确的实现吗?您正在使用索引来识别每辆车。这不是一个好习惯,我建议为每辆汽车添加一个唯一 ID,然后在选择一辆汽车时使用它来查询详细信息。
  • 是的,我正在研究它,但我做不到。还为模型中的每个元素添加了 Id 属性
  • 在我的模型中添加了 id 属性后。我用模型 id 更改了索引绑定,而不是 URL 索引,所以问题解决了,非常感谢我在这里所做的更改
猜你喜欢
  • 1970-01-01
  • 2021-07-22
  • 1970-01-01
  • 2017-04-28
  • 2020-05-30
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 2022-01-02
相关资源
最近更新 更多