Comment filtrer un tableau avec TypeScript dans Angular 2?
L'héritage de données parent-enfant Ng-2 a été une difficulté pour moi.
Ce qui semble être une bonne solution pratique est de filtrer mon tableau total de données dans un tableau composé uniquement de données enfants référencées par un identifiant parent unique. En d'autres termes: l'héritage de données devient un filtrage de données par un identifiant parent.
Dans un exemple concret, cela peut ressembler à: filtrer un tableau de livres pour afficher uniquement les livres avec un certain 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 est nouveau pour moi, mais je pense que je suis sur le point de faire fonctionner les choses ici.
(écraser également le tableau des livres originaux pourrait être une option, puis utiliser *ngFor="#book of books"
.)
Modifier Se rapprocher, mais toujours donner une erreur.
//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
3 réponses
, Vous devez mettre votre code dans ngOnInit
et utiliser le this
clé:
ngOnInit() {
this.booksByStoreID = this.books.filter(
book => book.store_id === this.store.id);
}
Vous avez besoin d' ngOnInit
, car l'entrée store
ne serait pas définie dans le constructeur:
NgOnInit est appelé juste après que les propriétés liées aux données de la directive ont été vérifiées pour la première fois, et avant que l'un de ses enfants ait été vérifié. Il est invoqué qu'une seule fois lorsque la directive est instancier.
(https://angular.io/docs/ts/latest/api/core/index/OnInit-interface.html)
Dans votre code, le filtrage des livres est directement défini dans le contenu de la classe...
, Vous pouvez consulter un exemple dans Plunker ici plunker exemple des filtres
filter() {
let storeId = 1;
this.bookFilteredList = this.bookList
.filter((book: Book) => book.storeId === storeId);
this.bookList = this.bookFilteredList;
}
Pour filtrer un tableau quel que soit le type de propriété (c'est-à-dire pour tous les types de propriétés), nous pouvons créer un tuyau de filtre personnalisé
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>
N'oubliez pas d'importer le tuyau dans le module app
Nous pourrions avoir besoin de personnaliser la logique de filer avec les dates.