it-swarm.com.de

Wie kann ich ein Array mit TypeScript in Angular 2 filtern?

ng-2 Eltern-Kind-Datenvererbung war für mich eine Schwierigkeit. 

Was anscheinend eine gut funktionierende praktische Lösung sein könnte, ist das Filtern meines gesamten Datenfelds in ein Feld, das nur aus untergeordneten Daten besteht, auf die eine einzelne übergeordnete ID verweist .. Mit anderen Worten: Datenvererbung wird zu einer Datenfilterung nach einer übergeordneten ID. 

In einem konkreten Beispiel kann dies wie folgt aussehen: Filtern eines Bücher-Arrays, um nur die Bücher mit einem bestimmten store_id anzuzeigen.

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 ist neu für mich, aber ich glaube, ich bin kurz davor, dass hier alles funktioniert.

(Das Überschreiben des ursprünglichen Bücher-Arrays könnte auch eine Option sein und dann *ngFor="#book of books" verwenden.)

EDIT Annäherung, aber immer noch ein Fehler.

//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
72
Code-MonKy

Sie müssen Ihren Code in ngOnInit eingeben und das Schlüsselwort this verwenden:

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

Sie benötigen ngOnInit, da die Eingabe store nicht im Konstruktor festgelegt wurde:

ngOnInit wird direkt nach der erstmaligen Überprüfung der datengebundenen Eigenschaften der Direktive und vor deren untergeordneten Elementen aufgerufen. Sie wird nur einmal aufgerufen, wenn die Direktive instanziiert wird.

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

In Ihrem Code wird die Bücherfilterung direkt in den Klasseninhalt definiert ...

133

Sie können ein Beispiel in Plunker hier überprüfen. Plunker Beispielfilter

filter() {

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

Um ein Array unabhängig vom Eigenschaftstyp (d. H. Für alle Eigenschaftstypen) zu filtern, können Sie eine benutzerdefinierte Filterleitung erstellen

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>

Vergessen Sie nicht, die Pipe im App-Modul zu importieren

Wir müssen möglicherweise die Logik anpassen, um Daten mit Datumsangaben zu speichern.

0
alchi baucha