首先,我想用这个管道显示国家并用插入的字符过滤它们,我需要 ISO 代码来显示国家的旗帜。问题是我想使用一个库,其中包含所有国家/地区的 ISO 代码和内容。这具有键值形式。
首先,我将这些数据导出到 var 以便能够使用这些数据。
export var indexedArray: { [key: string]: string }
countryStuff: Country; //currently not used
countries = [] as Array<string>
filteredCountries: Observable<string[]>;
export interface Country { //currently not used
[key: string]: string
}
ngOnInit() {
this.startDate.setFullYear(this.startDate.getFullYear() - 18);
this.buildForm();
this.filteredCountries = this.personalForm.controls['country'].valueChanges
.pipe(
startWith(''),
map(value => this._filter(value))
);
i18nIsoCountries.registerLocale(require("i18n-iso-countries/langs/en.json"));
i18nIsoCountries.registerLocale(require("i18n-iso-countries/langs/de.json"));
this.currentLanguage = this.translateService.currentLang;
indexedArray = i18nIsoCountries.getNames(this.currentLanguage);
for (let key in indexedArray) {
let value = indexedArray[key];
this.countries.push(value);
}
}
在 html 中我可以这样使用:
<mat-option *ngFor="let item of countryStuff | keyvalue:keepOriginalOrder" [value]="item.key">
Key: <b>{{item.key}}</b> and Value: <b>{{item.value}}</b>
</mat-option>
我也可以使用常规方式,但完全没有键值方式,就像 Angular 示例所说的那样(没有 TS 逻辑):
<mat-option *ngFor="let option of filteredCountries | async" [value]="option">
<span class="flag-icon flag-icon-de flag-icon-squared"></span>
{{option}}
</mat-option>
这只是给了我完整的国家/地区名称,例如 Algolia 之类的。
我在这里找到了一个想法https://long2know.com/2017/04/angular-pipes-filtering-on-multiple-keys/但我不能为了我的目的改变它。如果我可以针对 key 和 value 进行过滤,那就更完美了,所以也许“DE”代表德国的关键,“Ger”代表德国的值(value)。现有管道似乎不可能。
根据要求编辑(过滤):
private _filter(value: string): string[] {
var filterValue;
if (value) {
filterValue = value.toLowerCase();
} else {
filterValue = "";
}
return this.countries.filter(option => option.toLowerCase().startsWith(filterValue));
}
还更新了 ngOnInit()
最佳答案
我用 i18n
库甚至 flag-icon-css
TypeScript(过滤器类):
@Pipe({
name: 'filterLanguages'
})
export class FilterLanguages implements PipeTransform {
transform(items: any, filter: any, isAnd: boolean): any {
if (filter && Array.isArray(items)) {
let filterKeys = Object.keys(filter);
if (isAnd) {
return items.filter(item =>
filterKeys.reduce((memo, keyName) =>
(memo && new RegExp(filter[keyName], 'gi').test(item[keyName])) || filter[keyName] === "", true));
} else {
return items.filter(item => {
return filterKeys.some((keyName) => {
return new RegExp(filter[keyName], 'gi').test(item[keyName]) || filter[keyName] === "";
});
});
}
} else {
return items;
}
}
}
HTML:
<mat-form-field class="field-sizing">
<input matInput required placeholder="{{ 'REGISTRATION.COUNTRY' | translate }}" name="country"
id="country" [matAutocomplete]="auto" formControlName="country" [value]="filterText" />
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let item of countries | filterLanguages:{ name: filterText, iso: filterText, flagId: filterText } : false" [value]="item.name">
<span class="flag-icon flag-icon-{{item.flagId}} flag-icon-squared"></span>
{{ item.name }} - {{ item.iso }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
typescript (组件):
export var countryList: {
[key: string]: string
}
declare const require;
export class YourComponent implements OnInit {
countries = [] as Array<any>
currentLanguage: string;
filterText: string;
ngOnInit() {
i18nIsoCountries.registerLocale(require("i18n-iso-countries/langs/en.json"));
i18nIsoCountries.registerLocale(require("i18n-iso-countries/langs/de.json"));
this.currentLanguage = this.translateService.currentLang;
countryList = i18nIsoCountries.getNames(this.currentLanguage);
this.buildForm();
this.createCountries();
this.personalForm.controls['country']
.valueChanges
.pipe(debounceTime(100))
.pipe(distinctUntilChanged())
.subscribe(term => {
this.filterText = term;
});
}
ngAfterContentChecked() {
this.cdRef.detectChanges();
if (this.currentLanguage != this.translateService.currentLang) {
countryList = i18nIsoCountries.getNames(this.translateService.currentLang);
this.createCountries();
this.currentLanguage = this.translateService.currentLang;
this.personalForm.get('country').updateValueAndValidity();
}
}
createCountries() {
this.countries = [];
for (let key in countryList) {
var countryName: string = countryList[key];
var isoValue: string = key;
var isoLowerValue: string = key.toLowerCase();
this.countries.push({ name: countryName, iso: isoValue, flagId: isoLowerValue })
}
}
您需要 i18n 库,例如我的示例中的 formControl。
关于javascript - KeyValue 和 AutoComplete 的 Angular Filter Pipe,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56535386/