Как мне отфильтровать массив с помощью TypeScript в Angular 2?


110

ng-2 наследование родительско-дочерних данных было для меня проблемой.

Кажется, что это может быть прекрасным практическим решением, так это фильтрация моего общего массива данных в массив, состоящий только из дочерних данных, на которые ссылается единственный родительский идентификатор. Другими словами: наследование данных становится фильтрацией данных по одному родительскому идентификатору.

В конкретном примере это может выглядеть так: фильтрация массива книг для отображения только книг с определенным 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

Ответы:


205

Вам нужно ввести свой код 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 )

В вашем коде фильтрация книг напрямую определяется в содержимом класса ...


Имеет смысл. Я получаю сообщение об ошибке «Ошибка: ngOnInit не определен» после добавления вашего фрагмента кода, импорта OnInitи добавления booksByStoreID = Book[];компонента.
Code-MonKy

Думаю, что скорее:booksByStoreID: Book[];
Тьерри Темплиер

Тоже не работает. Может, стоит поместить это в конструктор? Я пробовал это, потом получаю сообщение об ошибке]
Code-MonKy

1
Спасибо! Фильтрация полностью работает :) Но возникла новая проблема. Если щелкнуть родительский компонент и выбрать другой магазин, старый store_id останется, а список книг останется прежним ...
Code-MonKy,

1
Превосходно. Поздравляю за 200 голосов !!!
Амук Саксена,


4

Чтобы фильтровать массив независимо от типа свойства (т.е. для всех типов свойств), мы можем создать настраиваемую трубу фильтра.

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>

Не забудьте импортировать канал в модуль приложения

Возможно, нам потребуется настроить логику для подачи файлов с датами.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.