【问题标题】:How do I filter an array with TypeScript in Angular 2?如何在 Angular 2 中使用 TypeScript 过滤数组?
【发布时间】:2016-08-28 11:08:38
【问题描述】:

ng-2 父子数据继承对我来说一直是个难题。

似乎一个可行的实用解决方案是将我的总数据数组过滤为一个数组,该数组仅由单个父 ID 引用的子数据组成。 换句话说:数据继承变成了一个父ID的数据过滤。

在一个具体的例子中,这可能看起来像:过滤书籍数组以仅显示具有特定store_id 的书籍。

import {Component, Input} from 'angular2/core';

export class Store {
  id: number;
  name: string;
}

export class Book {
  id: number;
  shop_id: number;
  title: string;
}

@Component({
  selector: 'book',
  template:`
    <p>These books should have a label of the shop: {{shop.id}}:</p>

    <p *ngFor="#book of booksByShopID">{{book.title}}</p>
  `
])
export class BookComponent {
  @Input()
  store: Store;

  public books = BOOKS;

  // "Error: books is not defined"
  // ( also doesn't work when books.filter is called like: this.books.filter
  // "Error: Cannot read property 'filter' of undefined" )
  var booksByStoreID = books.filter(book => book.store_id === this.store.id)
}

var BOOKS: Book[] = [
  { 'id': 1, 'store_id': 1, 'name': 'Dichtertje' },
  { 'id': 2, 'store_id': 1, 'name': 'De uitvreter' },
  { 'id': 3, 'store_id': 2, 'name': 'Titaantjes' }
];

TypeScript 对我来说是新的,但我认为我已经接近让事情在这里工作了。

(也可以选择覆盖原始书籍数组,然后使用*ngFor="#book of books"。)

编辑 越来越近,但仍然报错。

//changes on top:
import {Component, Input, OnInit} from 'angular2/core';

// ..omitted

//changed component:
export class BookComponent implements OnInit {
  @Input() 
  store: Store;

  public books = BOOKS;

  // adding the data in a constructor needed for ngInit
  // "EXCEPTION: No provider for Array!"
  constructor(
    booksByStoreID: Book[];
  ) {}


  ngOnInit() {
    this.booksByStoreID = this.books.filter(
      book => book.store_id === this.store.id);
  }
}

// ..omitted

【问题讨论】:

    标签: arrays filter typescript angular


    【解决方案1】:

    您需要将代码放入ngOnInit 并使用this 关键字:

    ngOnInit() {
      this.booksByStoreID = this.books.filter(
              book => book.store_id === this.store.id);
    }
    

    您需要ngOnInit,因为输入store 不会被设置到构造函数中:

    ngOnInit 在第一次检查指令的数据绑定属性之后,并且在检查其任何子项之前立即调用。当指令被实例化时,它只被调用一次。

    (https://angular.io/docs/ts/latest/api/core/index/OnInit-interface.html)

    在您的代码中,书籍过滤直接定义在类内容中...

    【讨论】:

    • 有道理。添加您的代码、导入OnInit 并在组件中添加booksByStoreID = Book[]; 后,我收到错误“错误:ngOnInit 未定义”。
    • 我认为是:booksByStoreID: Book[];
    • 也不起作用。我应该把它放在构造函数中吗?我试过这个,然后我收到一个错误,抱怨]
    • 您能否在问题中(例如在编辑段落中)添加您尝试过的代码?我很难猜出你尝试了什么 ;-) 谢谢!
    • 谢谢!过滤完全有效:) 但是出现了一个新问题。当单击父组件以选择另一个商店时,旧的 store_id 保持不变,书籍列表保持不变......
    【解决方案2】:

    您可以在此处查看 Plunker 中的示例plunker example filters

    filter() {
    
        let storeId = 1;
        this.bookFilteredList = this.bookList
                                    .filter((book: Book) => book.storeId === storeId);
        this.bookList = this.bookFilteredList; 
    }
    

    【讨论】:

      【解决方案3】:

      要过滤数组而不考虑属性类型(即针对所有属性类型),我们可以创建自定义过滤器管道

      import { Pipe, PipeTransform } from '@angular/core';
      
      @Pipe({ name: "filter" })
      export class ManualFilterPipe implements PipeTransform {
        transform(itemList: any, searchKeyword: string) {
          if (!itemList)
            return [];
          if (!searchKeyword)
            return itemList;
          let filteredList = [];
          if (itemList.length > 0) {
            searchKeyword = searchKeyword.toLowerCase();
            itemList.forEach(item => {
              //Object.values(item) => gives the list of all the property values of the 'item' object
              let propValueList = Object.values(item);
              for(let i=0;i<propValueList.length;i++)
              {
                if (propValueList[i]) {
                  if (propValueList[i].toString().toLowerCase().indexOf(searchKeyword) > -1)
                  {
                    filteredList.push(item);
                    break;
                  }
                }
              }
            });
          }
          return filteredList;
        }
      }
      
      //Usage
      
      //<tr *ngFor="let company of companyList | filter: searchKeyword"></tr>
      

      别忘了在应用模块中导入管道

      我们可能需要自定义逻辑以使用日期归档。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-13
        • 1970-01-01
        • 2017-10-12
        • 2018-01-15
        • 2017-03-02
        • 1970-01-01
        • 1970-01-01
        • 2021-01-14
        相关资源
        最近更新 更多