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
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 ...
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;
}
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.