typescript - Como usar este pipe no Angular 5 dinamicamente?
Estou usando pipe na minha aplicação Angular para filtrar valores de opções com base na entrada de pesquisa fornecida pelo usuário. Este filtro é usado no nível do campo de um formulário que é gerado dinamicamente usando o loop ngFor e baseado na resposta JSON.
Sou capaz de usar o conceito de pipe para filtrar o valor de uma entrada única independente, mas quando o uso várias vezes usando o loop NgFor como no código abaixo, ele não funciona perfeitamente.
// 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>
Isso me dá uma saída assim.
Agora o problema é que searchText atribuído ao ngmodel não pode ser usado mais de uma vez, pois está vinculado a apenas um input e, se eu fizer isso, também afetará os outros inputs.
Como passar [(ngmodel)] ="some_variable" e depois atribuí-lo a filteroptions: "some_variable" para que eles estejam vinculados a apenas uma entrada de seleção???
Então, o problema também pode ser expresso como como passar um nome dynamic ngmodel e atribuir esse nome aos parâmetros do pipe?
Este é o pipe filteroptions que estou usando.
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);
});
}
}
Resposta #1
O problema que você está vendo é basicamente devido a todos os inputs ngx-mat-select-search estarem vinculados bidirecionalmente ao mesmo campo, searchText. Você pode contornar isso facilmente introduzindo uma variável de template para o seu filtro.
<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>
Resposta #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);
}
}
