l'héritage de données ng-2 parent-enfant a été une difficulté pour moi.
Ce qui semble être une bonne solution pratique est de filtrer mon tableau total de données en un tableau composé uniquement de données enfants référencées par un seul identifiant parent ..__ 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 n’afficher que 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.
(Le remplacement du tableau de livres d'origine peut également être une option, puis d'utiliser *ngFor="#book of books"
.)
EDIT Se rapprocher, mais en générant 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
Vous devez mettre votre code dans ngOnInit
et utiliser le mot clé this
:
ngOnInit() {
this.booksByStoreID = this.books.filter(
book => book.store_id === this.store.id);
}
Vous avez besoin de ngOnInit
car l'entrée store
ne serait pas définie dans le constructeur:
ngOnInit est appelée 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 qu'aucun de ses enfants n'ait été vérifié. Elle n'est invoquée qu'une seule fois lorsque la directive est instanciée.
( 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 exemple de filtres plunker
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 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 d'application
Nous pourrions avoir besoin de personnaliser la logique pour Filer avec des dates.