custom array string angular typescript filter ngfor

string - array - Cómo filtrar elementos dentro del bucle "ngFor", en función de la cadena de propiedad del objeto



filter json angular 4 (1)

Necesito filtrar elementos dentro de un bucle ngFor , cambiando la categoría en una lista desplegable. Por lo tanto, cuando se selecciona una categoría particular de la lista, solo debe enumerar los elementos que contienen esa misma categoría.

Plantilla HTML:

<select> <option *ngFor="let model of models">{{model.category}}</option> </select> <ul class="models"> <li *ngFor="let model of models" (click)="gotoDetail(model)"> <img [src]="model.image"/> {{model.name}},{{model.category}} </li> </ul>

Items Array:

export var MODELS: Model[] = [ { id: 1, name: ''Model 1'', image: ''img1'', category: ''Cat1'', }, { id: 2, name: ''Model 2'', image: ''img2'', category: ''Cat3'', }, { id: 3, name: ''Model 3'', image: ''img3'', category: ''Cat1'', }, { id: 4, name: ''Model 4'', image: ''img4'', category: ''Cat4'', }, ... ];

Además, la lista desplegable contiene nombres de categoría repetidos. Es necesario que enumere solo categorías únicas (cadenas).

Sé que crear un conducto personalizado sería la forma correcta de hacerlo, pero no sé cómo escribir uno.

Plunker: http://plnkr.co/edit/tpl:2GZg5pLaPWKrsD2JRted?p=preview


Aquí hay un tubo de muestra:

import { Pipe, PipeTransform } from ''@angular/core''; @Pipe({ name: ''matchesCategory'' }) export class MathcesCategoryPipe implements PipeTransform { transform(items: Array<any>, category: string): Array<any> { return items.filter(item => item.category === category); } }

Para usarlo:

<li *ngFor="let model; of models | matchesCategory:model.category" (click)="gotoDetail(model)">

===== para el ejemplo de Plunkr ====

Necesita sus cambios seleccionados para reflejar en alguna variable

Primero defina en su clase un miembro:

selectedCategory: string;

luego actualiza tu plantilla:

<select (change)="selectedCategory = $event.target.value"> <option *ngFor="let model of models ">{{model.category}}</option> </select>

por último, usa la tubería:

<li *ngFor="let model; of models | matchesCategory:selectedCategory" (click)="gotoDetail(model)">

==== comentarios después de ver el plunker ====

Noté que usaste la promesa. Angular2 está más orientado a rxjs. Entonces, lo primero que cambiaría es a su servicio, reemplace:

getModels(): Promise<Model[]> { return Promise.resolve(MODELS); }

a:

getModels(): Observable<Array<Model>> { return Promise.resolve(MODELS); }

y

getModels(id: number): Observable<Model> { return getModels().map(models => models.find(model.id === id); }

luego en su ModelsComponent

models$: Observable<Array<Model>> = svc.getModels(); uniqueCategories$: Observable<Array<Model>> = this.models$ .map(models => models.map(model => model.category) .map(categories => Array.from(new Set(categories)));

Tus opciones se convertirán en:

<option *ngFor="let category; of uniqueCategories$ | async">{{model.category}}</option>

y tu lista:

<li *ngFor="let model; of models$ | async | matchesCategory:selectedCategory" (click)="gotoDetail(model)">

Esta es una solución muy dispersa ya que tiene muchos duplicados y sigue consultando el servicio. Toma esto como punto de partida y consulta el servicio solo una vez, luego deriva valores específicos del resultado que obtuviste.

Si desea mantener el código, simplemente implemente un UniqueValuesPipe, su transformación obtendrá un único parámetro y lo filtrará para devolver categorías únicas usando Array.from(new Set(...)) . Sin embargo, primero necesitará asignarlo a cadenas (categorías).