导入我的自定义过滤器的对象数组始终显示为零长度 [英] Array of objects piped into my custom filter always shows as length of zero

查看:12
本文介绍了导入我的自定义过滤器的对象数组始终显示为零长度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

像这样在我的视图中循环遍历一个对象数组(没有管道,我会显示整个列表):

Am looping over an array of object in my view like this (without the pipe I get the whole list displayed):

  <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 属性的类别,如下所示:

I am feeding the array into a custom pipe called onlyhomecategory to filter out any categories that don't have a home property like this:

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
});

}}

我不确定哪里出错了.如果没有自定义管道,我的视图会显示所有类别,但我似乎无法让管道正常工作.

Am not sure where am going wrong. Without the custom pipe, my view shows all the categories but I can't seem to get the pipe to work.

推荐答案

Angular 不会监控数组内容的变化.因为您使用空数组初始化 productCategories 并稍后将元素添加到同一数组中,所以更改检测不会检测到更改并且不会再次调用管道.

Angular doesn't monitor array content changes. Because you initialize productCategories with an empty array and later add elements to this same array, change detection doesn't detect the change and doesn't invoke the pipe again.

纯:假

您可以使管道不纯,因此每次更改检测运行时都会调用它,而不仅仅是在管道输入更改时

You can make the pipe impure, so it gets called every time change detection runs, not only when the pipe input changes

@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 运行更改检测时).为了不造成太大的伤害,请确保管道不会做昂贵的工作.例如,只要相关输入没有改变,就尝试缓存昂贵计算的结果.您需要自己跟踪以前的值和新值.

Making a pipe impure has performance implications, because the pipe is called a lot (every time Angular runs change detection). To not cause this too much harm, ensure that the pipe doesn't do expensive work. For example try to cache the result of expensive calculations as long as the relevant inputs haven't changed. You need to keep track of previous and new values yourself.

不同的对象

您还可以让 Angular 检测更改,不仅可以添加内容,还可以创建一个新的 - 不同的 - 数组.

You can also make Angular detect the change, by not only adding content but creating a new - different - array.

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
});

缺点:

如果数组很大,复制可能会很昂贵.

If the array is large, copying can be expensive.

提示

如果你修改一个已经包含值的数组,你可以使用 slice() 创建一个副本:

If you modify an array that already contains values you can create a copy using 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
});

Plunker 示例

这篇关于导入我的自定义过滤器的对象数组始终显示为零长度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆