通过管道传输到我的自定义过滤器中的对象数组始终显示为零长度
Array of objects piped into my custom filter always shows as length of zero
我像这样在我的视图中循环对象数组(没有管道,我显示了整个列表):
<ion-list>
<ion-item *ngFor= "let category of (productCategories | onlyhomecategory) " >
<ion-icon name="arrow-forward" item-right></ion-icon>
{{category.title}}
</ion-item>
</ion-list>
我将数组输入到一个名为 onlyhomecategory
的自定义管道中,以过滤掉任何没有 home
属性 的类别,如下所示:
import {Injectable, Pipe} from '@angular/core';
@Pipe({
name: 'onlyhomecategory'
})
@Injectable()
export class OnlyHomeCategories {
transform(productCategories: any[] , args: any[]) {
console.log(productCategories.length); //retuns 0
//If I hard-code/mock the array, pipe works as expected.
return productCategories.filter(category => category.home);
}
}
这是数组的形状:
[
{
home: 1,
title: "Greevy Swaney",
text: "Find the right area",
},
{
home: 2,
title: "Taney Wearx",
text: "Choose the right system",
},
{
title: "Tine rider",
},
{
title: "Shade",
}
];
这是服务:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class ProductCategories {
data: any = null;
constructor(public http: Http) {}
load() {
if (this.data) {
// already loaded data
return Promise.resolve(this.data);
}
// don't have the data yet
return new Promise(resolve => {
this.http.get('https://xxxxxxxxxxxxxxxxxxxxxxxx')
.map(res => res.json())
.subscribe(data => {
this.data = data;
resolve(this.data);
});
});
}
}
这是视图组件:
import {Page, NavController} from 'ionic-angular';
import {Inject} from '@angular/core'
import {ProductCategories} from '../../providers/product-categories/product-categories'
import {OnlyHomeCategories} from '../../pipes/only-home-categories'
@Page({
templateUrl: 'build/pages/product-category/product-category.html',
pipes: [OnlyHomeCategories]
})
export class ProductCategoryPage {
public productCategories = [];
constructor(public nav: NavController, private prodCat: ProductCategories) {
this.prodCat.load()
.then(data => {
for (var key in data) {
if (data.hasOwnProperty(key)) {
this.productCategories.push(data[key]);
}
}
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});
}
}
我不确定哪里出了问题。如果没有自定义管道,我的视图会显示所有类别,但我似乎无法让管道正常工作。
也许你应该删除 args: any[]
看这个例子:https://angular.io/docs/ts/latest/guide/pipes.html
import { Pipe, PipeTransform } from '@angular/core';
import { Flyer } from './heroes';
@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
transform(allHeroes:Flyer[]) {
return allHeroes.filter(hero => hero.canFly);
}
}
Angular 不监控数组内容变化。因为您使用空数组初始化 productCategories 并稍后将元素添加到同一数组,所以更改检测不会检测到更改并且不会再次调用管道。
纯:假
您可以使管道不纯,因此每次运行变化检测时都会调用它,而不仅仅是在管道输入发生变化时调用
@Pipe({
name: 'onlyhomecategory',
pure: false
})
export class OnlyHomeCategories {
transform(productCategories: any[] , args: any[]) {
console.log(productCategories.length); //retuns 0
return productCategories.filter(category => category.home);
}
}
缺点:
使管道不纯会对性能产生影响,因为管道被调用很多次(每次 Angular 运行更改检测)。
为了不造成太大的伤害,请确保管道不会做昂贵的工作。例如,只要相关输入没有改变,就尝试缓存昂贵的计算结果。您需要自己跟踪以前的值和新值。
不同对象
您还可以让 Angular 检测更改,不仅要添加内容,还要创建一个新的 - 不同的 - 数组。
this.prodCat.load()
.then(data => {
let arr = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
arr.push(data[key]);
}
}
this.productCategories = arr;
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});
缺点:
如果数组很大,复制可能会很昂贵。
提示
如果您修改一个已经包含值的数组,您可以使用 slice()
:
创建一个副本
this.prodCat.load()
.then(data => {
for (var key in data) {
if (data.hasOwnProperty(key)) {
this.productCategories.push(data[key]);
}
}
this.productCategories = this.productCategories.slice();
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});
我像这样在我的视图中循环对象数组(没有管道,我显示了整个列表):
<ion-list>
<ion-item *ngFor= "let category of (productCategories | onlyhomecategory) " >
<ion-icon name="arrow-forward" item-right></ion-icon>
{{category.title}}
</ion-item>
</ion-list>
我将数组输入到一个名为 onlyhomecategory
的自定义管道中,以过滤掉任何没有 home
属性 的类别,如下所示:
import {Injectable, Pipe} from '@angular/core';
@Pipe({
name: 'onlyhomecategory'
})
@Injectable()
export class OnlyHomeCategories {
transform(productCategories: any[] , args: any[]) {
console.log(productCategories.length); //retuns 0
//If I hard-code/mock the array, pipe works as expected.
return productCategories.filter(category => category.home);
}
}
这是数组的形状:
[
{
home: 1,
title: "Greevy Swaney",
text: "Find the right area",
},
{
home: 2,
title: "Taney Wearx",
text: "Choose the right system",
},
{
title: "Tine rider",
},
{
title: "Shade",
}
];
这是服务:
import {Injectable} from '@angular/core';
import {Http} from '@angular/http';
import 'rxjs/add/operator/map';
@Injectable()
export class ProductCategories {
data: any = null;
constructor(public http: Http) {}
load() {
if (this.data) {
// already loaded data
return Promise.resolve(this.data);
}
// don't have the data yet
return new Promise(resolve => {
this.http.get('https://xxxxxxxxxxxxxxxxxxxxxxxx')
.map(res => res.json())
.subscribe(data => {
this.data = data;
resolve(this.data);
});
});
}
}
这是视图组件:
import {Page, NavController} from 'ionic-angular';
import {Inject} from '@angular/core'
import {ProductCategories} from '../../providers/product-categories/product-categories'
import {OnlyHomeCategories} from '../../pipes/only-home-categories'
@Page({
templateUrl: 'build/pages/product-category/product-category.html',
pipes: [OnlyHomeCategories]
})
export class ProductCategoryPage {
public productCategories = [];
constructor(public nav: NavController, private prodCat: ProductCategories) {
this.prodCat.load()
.then(data => {
for (var key in data) {
if (data.hasOwnProperty(key)) {
this.productCategories.push(data[key]);
}
}
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});
} }
我不确定哪里出了问题。如果没有自定义管道,我的视图会显示所有类别,但我似乎无法让管道正常工作。
也许你应该删除 args: any[]
看这个例子:https://angular.io/docs/ts/latest/guide/pipes.html
import { Pipe, PipeTransform } from '@angular/core';
import { Flyer } from './heroes';
@Pipe({ name: 'flyingHeroes' })
export class FlyingHeroesPipe implements PipeTransform {
transform(allHeroes:Flyer[]) {
return allHeroes.filter(hero => hero.canFly);
}
}
Angular 不监控数组内容变化。因为您使用空数组初始化 productCategories 并稍后将元素添加到同一数组,所以更改检测不会检测到更改并且不会再次调用管道。
纯:假
您可以使管道不纯,因此每次运行变化检测时都会调用它,而不仅仅是在管道输入发生变化时调用
@Pipe({
name: 'onlyhomecategory',
pure: false
})
export class OnlyHomeCategories {
transform(productCategories: any[] , args: any[]) {
console.log(productCategories.length); //retuns 0
return productCategories.filter(category => category.home);
}
}
缺点:
使管道不纯会对性能产生影响,因为管道被调用很多次(每次 Angular 运行更改检测)。 为了不造成太大的伤害,请确保管道不会做昂贵的工作。例如,只要相关输入没有改变,就尝试缓存昂贵的计算结果。您需要自己跟踪以前的值和新值。
不同对象
您还可以让 Angular 检测更改,不仅要添加内容,还要创建一个新的 - 不同的 - 数组。
this.prodCat.load()
.then(data => {
let arr = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
arr.push(data[key]);
}
}
this.productCategories = arr;
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});
缺点:
如果数组很大,复制可能会很昂贵。
提示
如果您修改一个已经包含值的数组,您可以使用 slice()
:
this.prodCat.load()
.then(data => {
for (var key in data) {
if (data.hasOwnProperty(key)) {
this.productCategories.push(data[key]);
}
}
this.productCategories = this.productCategories.slice();
console.log(`this.productCategories.length: ${this.productCategories.length}`); // this return correct length
});