typescript - Cum să folosești acest pipe în Angular 5 dinamic?
Folosesc un pipe în aplicația mea Angular pentru a filtra valorile opțiunilor pe baza inputului de căutare dat de utilizator. Acest filtru este folosit la nivelul câmpului unui formular care este generat dinamic folosind bucla ngFor și pe baza răspunsului JSON.
Sunt capabil să folosesc conceptul de pipe pentru a filtra valoarea pentru o singură intrare independentă, dar atunci când îl folosesc de mai multe ori folosind bucla NgFor, ca în codul de mai jos, nu funcționează perfect.
// formdata is coming as of json response from a http request
<div *ngFor="let input1 of formdata.formfields">
<mat-select placeholder="Select something" [formControlName]="input1.field_name">
<ngx-mat-select-search [(ngModel)]="searchText" [ngModelOptions]="{standalone: true}" placeholder="Select {{input1.title}}"></ngx-mat-select-search>
// here I am using 'fitleroptions' pipe after ngFor and passing searchText ngmodel input binding
<mat-option *ngFor="let opt_value of input1.enumNameGroups | filteroptions : searchText; let i = index" value={{input1.value}}>{{opt_value}}</mat-option>
</mat-select>
// other input types like file, text etc....
</div>
Asta îmi dă un rezultat ca acesta.
Acum problema este că searchText asignat la ngModel nu poate fi folosit de mai multe ori deoarece este legat doar de un singur input și dacă fac asta, afectează și celelalte inputuri.
Cum să trec [(ngModel)] ="some_variable" și apoi să îl atribui lui filteroptions: "some_variable" astfel încât să fie legate doar de un singur input de selecție???
Deci problema poate fi exprimată și ca cum să treci un nume ngmodel dinamic și să atribui acel nume parametrilor pipe-ului?
Acesta este filtrul pipe options pe care îl folosesc.
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filteroptions'
})
export class FilterOptionsPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
if(!items) return [];
if(!searchText) return items;
searchText = searchText.toLowerCase();
return items.filter( it => {
console.log("got item array here",items);
return it.toLowerCase().includes(searchText);
});
}
}
Răspuns #1
Problema pe care o vezi apare practic din cauza faptului că toate câmpurile ngx-mat-select-search sunt legate bidirecțional de același câmp, searchText. Poți să o eviți cu ușurință introducând o variabilă de template pentru filtrul tău.
<ngx-mat-select-search ngModel #filter="ngModel" [ngModelOptions]="{standalone: true}" placeholder="Select {{input1.title}}"></ngx-mat-select-search>
<mat-option *ngFor="let opt_value of input1.enumNameGroups | filteroptions : filter.value; let i = index" value={{input1.value}}>{{opt_value}}</mat-option>
Răspunsul #2
<mat-select
placeholder="Owner"
[(ngModel)]="criteriaOwner"
name="ownerId"
required>
<ngx-mat-select-search ngModel
#filter="ngModel"
[ngModelOptions]="{standalone: true}"
[placeholderLabel]="'Find owner...'"
[noEntriesFoundLabel]="'No matching owner found'" >
</ngx-mat-select-search>
<mat-option *ngFor="let item of criteriaOwners | filterByProperty:
['name',filter.value]; let i = index" [value]="item">
<div fxLayout="row" fxLayoutGap="8px" fxLayoutAlign="start center">
<div>
{{item.name}}
</div>
</div>
</mat-option>
</mat-select>
/*Write pipe like below.*/
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterByProperty'
})
export class FilterByPropertyPipe implements PipeTransform {
transform(list: any[], args?: any): any {
if (!list || !args) {
return list;
}
var columnName = args[0];
var columnValue = args[1];
return list.filter(listItem => ('' + listItem[columnName]).toLocaleLowerCase().indexOf(columnValue.toString().toLocaleLowerCase()) !== -1);
}
}
