Angular 2 管道 - 无法读取未定义的 属性 'toString'
Angular 2 Pipe - Cannot read property 'toString' of undefined
我在 angular 2 中设置了搜索管道。当我在 angular beta 14 时,搜索管道工作正常,现在我升级到 rc5,搜索管道坏了,我得到错误。如果我从产品加载的 html 代码中删除管道。它是一个通用的搜索和过滤管道,应该在许多模块中使用。请帮助解决问题。
TypeError: Cannot read property 'toString' of undefined
at SearchPipe.compareWithAllFields (http://localhost:4200/main.bundle.js:72117:57)
at Array.filter (native)
at SearchPipe.transform
search.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import {isObject} from "rxjs/util/isObject";
import {isEmpty} from "rxjs/operator/isEmpty";
import {empty} from "rxjs/Observer";
@Pipe({
name: 'search'
})
export class SearchPipe implements PipeTransform
{
transform(input, [searchString]:Array<String>)
{
if (input == null) return input;
return input.filter(this.compareWithAllFields, searchString);
}
compareWithAllFields(value, index)
{
var fields = Object.keys(value);
for (let i = 0; i < fields.length; i++)
{
if (value[fields[i]] != null)
{
if (isObject(value[fields[i]]))
{
var childFields = Object.keys(value[fields[i]]);
if (childFields.length > 0)
{
for (let j = 0; j < childFields.length; j++)
{
if ((value[fields[i]][childFields[j]] + "").indexOf(this.toString()) !== -1)
{
return true;
}
}
}
}
if ((value[fields[i]] + "").indexOf(this.toString()) !== -1)
{
return true;
}
}
}
return false;
}
}
列表-products.component.html
<div class="container">
<div class="row">
<div class="col-sm-3 form-group">
<input placeholder="search product" class="form-control" type="text" #searchProduct (keyup)="0">
</div>
<div class="col-sm-3 col-sm-offset-6">
<button [routerLink]="['/LoggedIn','Product','ProductAdd']" class="btn btn-lg btn-app">Add Product</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h3>Products</h3>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Sr #</th>
<th>Name</th>
<th>Category</th>
<th>Barcode</th>
<th>Unit</th>
<th>Description</th>
<th>Quantity</th>
<th>Minimum Stock Level</th>
<th>Discount</th>
<th>Cost</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products | search:searchProduct.value;let serial = index">
<td>{{ serial+1 }}</td>
<td>{{ product.name}}</td>
<td>{{ product.productCategory.name}}</td>
<td>{{ product.barcode}}</td>
<td>{{ product.unit?.name}}</td>
<td>{{ product.description}}</td>
<td>{{ product.quantity}}</td>
<td>{{ product.minimumStockLevel}}</td>
<td>{{ product.discount}}</td>
<td>{{ product.cost}}</td>
<td>
<button class="btn btn-danger" (click)="delete(product)">Delete</button>
<button class="btn btn-default"
[routerLink]="['/LoggedIn','Product','ProductEdit',{id:product.id}]">Edit
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
我想你需要改变
return input.filter(this.compareWithAllFields, searchString);
至
return input.filter(this.compareWithAllFields.bind(this), searchString);
解决方案:
将 transform(input, [searchString]:Array<String>)
更改为 transform(input, searchString)
@usmanwalana,自 RC3/4 以来,PIPE API 发生了变化,它现在 returns 作为字符串而不是数组的第二个参数。
所以改变,
transform(input, [searchString]:Array<String>)
到
transform(input, searchString)
我在 angular 2 中设置了搜索管道。当我在 angular beta 14 时,搜索管道工作正常,现在我升级到 rc5,搜索管道坏了,我得到错误。如果我从产品加载的 html 代码中删除管道。它是一个通用的搜索和过滤管道,应该在许多模块中使用。请帮助解决问题。
TypeError: Cannot read property 'toString' of undefined
at SearchPipe.compareWithAllFields (http://localhost:4200/main.bundle.js:72117:57)
at Array.filter (native)
at SearchPipe.transform
search.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
import {isObject} from "rxjs/util/isObject";
import {isEmpty} from "rxjs/operator/isEmpty";
import {empty} from "rxjs/Observer";
@Pipe({
name: 'search'
})
export class SearchPipe implements PipeTransform
{
transform(input, [searchString]:Array<String>)
{
if (input == null) return input;
return input.filter(this.compareWithAllFields, searchString);
}
compareWithAllFields(value, index)
{
var fields = Object.keys(value);
for (let i = 0; i < fields.length; i++)
{
if (value[fields[i]] != null)
{
if (isObject(value[fields[i]]))
{
var childFields = Object.keys(value[fields[i]]);
if (childFields.length > 0)
{
for (let j = 0; j < childFields.length; j++)
{
if ((value[fields[i]][childFields[j]] + "").indexOf(this.toString()) !== -1)
{
return true;
}
}
}
}
if ((value[fields[i]] + "").indexOf(this.toString()) !== -1)
{
return true;
}
}
}
return false;
}
}
列表-products.component.html
<div class="container">
<div class="row">
<div class="col-sm-3 form-group">
<input placeholder="search product" class="form-control" type="text" #searchProduct (keyup)="0">
</div>
<div class="col-sm-3 col-sm-offset-6">
<button [routerLink]="['/LoggedIn','Product','ProductAdd']" class="btn btn-lg btn-app">Add Product</button>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<h3>Products</h3>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Sr #</th>
<th>Name</th>
<th>Category</th>
<th>Barcode</th>
<th>Unit</th>
<th>Description</th>
<th>Quantity</th>
<th>Minimum Stock Level</th>
<th>Discount</th>
<th>Cost</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let product of products | search:searchProduct.value;let serial = index">
<td>{{ serial+1 }}</td>
<td>{{ product.name}}</td>
<td>{{ product.productCategory.name}}</td>
<td>{{ product.barcode}}</td>
<td>{{ product.unit?.name}}</td>
<td>{{ product.description}}</td>
<td>{{ product.quantity}}</td>
<td>{{ product.minimumStockLevel}}</td>
<td>{{ product.discount}}</td>
<td>{{ product.cost}}</td>
<td>
<button class="btn btn-danger" (click)="delete(product)">Delete</button>
<button class="btn btn-default"
[routerLink]="['/LoggedIn','Product','ProductEdit',{id:product.id}]">Edit
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
我想你需要改变
return input.filter(this.compareWithAllFields, searchString);
至
return input.filter(this.compareWithAllFields.bind(this), searchString);
解决方案:
将 transform(input, [searchString]:Array<String>)
更改为 transform(input, searchString)
@usmanwalana,自 RC3/4 以来,PIPE API 发生了变化,它现在 returns 作为字符串而不是数组的第二个参数。
所以改变,
transform(input, [searchString]:Array<String>)
到
transform(input, searchString)