Angular 2 Price Filter Pipe - 无法读取未定义的属性“0”

时间:2016-10-26 15:56:51

标签: angular typescript angular2-forms angular2-pipe pipes-filters

我想创建一个价格过滤器,根据两个变量过滤掉产品。这两个变量是最低价格和最高价格。

目前我只实施了最低价格,以便让事情更容易理解。但是在* ngFor指令之后添加| priceFilter:priceMinFilter管道时,我收到此“Cannot read property '0' of undefined”错误。

我正试图解决这个问题,任何人都可以提出一些建议或者告诉我这里我做错了什么?谢谢。

这是一个插件:https://plnkr.co/tU82lO

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: 'src/app.html',
  styleUrls: ['src/app.css']
})

export class App {

  @Input() priceMinFilter: number;

  filterPrice(filter) {
    this.priceMinFilter = filter.priceMin;
  }

  _productList = [
    {
      "name": "Product One",
      "price": 600,
    },
    {
      "name": "Product Two",
      "price": 1100,
    },
    {
      "name": "Product Three",
      "price": 2150,
    },
    {
      "name": "Product Four",
      "price": 3500,
    },
    {
      "name": "Product Five",
      "price": 4300,
    },
    {
      "name": "Product Six",
      "price": 5400,
    },
    {
      "name": "Product Seven",
      "price": 6900,
    },
    {
      "name": "Product Eighth",
      "price": 14000,
    },
    {
      "name": "Product Nine",
      "price": 26000,
    },
    {
      "name": "Product Ten",
      "price": 30000,
    },
    {
      "name": "Product Eleven",
      "price": 160000,
    },
    {
      "name": "Product Twelve",
      "price": 1000000,
    }
  ]

}

app.component.html

<!-- Title -->
<h2 class="title">Price Filter Pipe with Data Driven Form Approach</h2>

<!-- Filter -->
<zt-filter (filterPrice)='filterPrice($event)'></zt-filter>

<!-- Notification -->
<div class="note" *ngIf="priceMinFilter">
    <span>Filtering Products from <strong>{{ priceMinFilter }}</strong></span>
</div>

<!--Product List -->
<div class="price-list">
    <div class="product-item" *ngFor="let _product of _productList | priceFilter:priceMinFilter">
        <span class="name">{{ _product.name }}</span><span class="price">{{ _product.price | currency:'USD':true:'1.0-2' }}</span>
    </div>
</div>

filter.component.ts

@Component({
  selector: 'zt-filter',
  templateUrl: 'src/filter.component.html',
  styleUrls: ['src/filter.component.css']
})
export class FilterComponent implements OnInit {

 // Initializing Properties
  priceMinFilter: number;

  priceFilterForm: FormGroup;

  // Outputs
  @Output() filterPrice: EventEmitter<{
    priceMin: number,
  }> = new EventEmitter<{
    priceMin: number,
  }>();

  // Constructor
  constructor() {
    this.priceFilterForm = new FormGroup({
      priceMin: new FormControl('any')
    });

    this.priceFilterForm.controls['priceMin'].valueChanges.subscribe(
      (data: any) => console.log(data)
    )
  }

  // From Actions
  onSubmit() {
    this.filterPrice.emit({
      priceMin: this.priceMinFilter
    });
  }

  // Data
  _priceOptions = [
    { "valueP": null },  
    { "valueP": 500 }, 
    { "valueP": 1000 }, 
    { "valueP": 2000 }, 
    { "valueP": 3000 }, 
    { "valueP": 4000 }, 
    { "valueP": 5000 }, 
    { "valueP": 10000 }, 
    { "valueP": 20000 }, 
    { "valueP": 30000 }, 
    { "valueP": 40000 }, 
    { "valueP": 50000 }, 
    { "valueP": 60000 }, 
    { "valueP": 70000 },
    { "valueP": 80000 }, 
    { "valueP": 90000 }, 
    { "valueP": 100000 }, 
    { "valueP": 150000 }, 
    { "valueP": 200000 }
  ]
}

filter.component.html

<form [formGroup]="priceFilterForm" class="price-filter-form" autocomplete="off" novalidate (ngSubmit)="onSubmit()">
    <div class="form-group">

        <!-- Min Price Select -->
        <label for="price-min">Min Price</label>
        <select id="price-min" class="form-control" name="pricemin" [(ngModel)]="priceMinFilter" formControlName="priceMin">
      <option *ngFor="let _priceMin of _priceOptions" [value]="_priceMin.valueP">{{ _priceMin.valueP | currency:'USD':true:'1.0-2' }}</option>
    </select>

        <!-- Filter Button -->
        <button type="submit">Filter by Minimum Price!</button>

    </div>
</form>

filter.pipe.ts

@Pipe({
  name: 'priceFilter'
})
export class PriceFilterPipe implements PipeTransform {

  transform(value, args?) {
    // ES6 array destructuring
    let [minPrice] = args;
    return value.filter(_product => {
        return _product.valueP >= +minPrice;
    });
  }
}

谢谢!

1 个答案:

答案 0 :(得分:0)

我设法通过创建自定义过滤器管道解决了这个问题。

您可以在以下位置查看存储库: https://github.com/cstodor/Angular2-Price-Filter

filter.pipe.ts

transform(list, minPrice: number | undefined, maxPrice:number | undefined) {
  let filter_list = list;
  if (minPrice) {
    filter_list = filter_list.filter(_item => {
      return _item.price >= +minPrice;
    });
  } 

  if (maxPrice) {
    filter_list = filter_list.filter(_item => {
      return _item.price <= +maxPrice;
    });
  }
  return  filter_list;
}

app.component.html

<!-- Title -->
<h2 class="title">Price Filter Pipe with Data Driven Form Approach</h2>

<!-- Filter -->
<zt-filter (filterPrice)='filterPrice($event)' ></zt-filter>

<!-- Notification -->
<div class="note" *ngIf="priceMinFilter || priceMaxFilter">
    <span *ngIf="priceMinFilter">Filtering Products from <strong>${{ priceMinFilter }}</strong></span>
    <span *ngIf="priceMaxFilter"> to <strong>${{ priceMaxFilter }}</strong>.</span>
</div>

<!--Product List -->
<div class="price-list">
    <div class="product-item" *ngFor="let _product of (_productList | priceFilter:priceMinFilter:priceMaxFilter)">
        <span class="name">{{ _product.name }}</span><span class="price">{{ _product.price | currency:'USD':true:'1.0-2' }}</span>
    </div>
</div>