angular - 通过管道传输到我的自定义过滤器中的对象数组始终显示为零长度

标签 angular ionic2

我像这样在我的 View 中循环对象数组(没有管道,我显示了整个列表):

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

这是 View 组件:

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

}

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

最佳答案

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

Plunker example

关于angular - 通过管道传输到我的自定义过滤器中的对象数组始终显示为零长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37722921/

相关文章:

angular - 计算 ag-grid 中选定行的数量

angular - Rxjs - 条件可管道运算符

javascript - 当我在手机屏幕上触摸和移动时,如何记录触摸轨迹(x 和 y 坐标)?

angular - 带 ngrx-store 的 Ionic 无限滚动

angular - ionic 3 Angular 访问 viewchild 到其他页面

Angular 8,启动时出现 IE11 错误 Function.prototype.toString : 'this' is not a Function object

javascript - 如何清除 Angular 中组合框的选定值

angular - 使用 createReducer 函数时为生产构建 angular+ngrx 8 时出错

angular - 如何使用 float 标签进行 ionic 选择

javascript - 为什么构建表单时页面的属性未定义