#angular #typescript
#angular #typescript
Вопрос:
Через веб-сервис я отправляю на интерфейс Json и сопоставляю его для помещения всего его содержимого в таблицу, и я хочу установить метод поиска для просмотра только строк, содержащих искомые буквы.
Component.ts
allCountries:allCountries[];
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.allCountries.filter = filterValue.trim().toLowerCase();
} ^^^^^^^^^^^^
ERROR
сопоставление
export class allCountries{
name:string;
iso2:string;
iso3:string;
unicode:string;
dial:string;
currency:string;
capital:string;
continent:string;
}
HTML
<mat-label for="ricerca">Ricerca</mat-label>
<input matInput type="text" name="searchString" (keyup)="applyFilter($event)" placeholder="Type to search..." />
<table mat-table [dataSource]="allCountries">
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef>Nazione</th>
<td mat-cell *matCellDef="let allCountries">{{allCountries.name}}</td>
</ng-container>
<ng-container matColumnDef="iso2">
<th mat-header-cell *matHeaderCellDef>iso 2</th>
<td mat-cell *matCellDef="let allCountries">{{allCountries.iso2}}</td>
</ng-container>
ошибка
error TS2322: Type 'string' is not assignable to type '{ <S extends allCountries>(callbackfn: (value: allCountries, index: number, array: allCountries[]) => value is S, thisArg?: any): S[]; (callbackfn: (value: allCountries, index: number, array: allCountries[]) => unknown, thisArg?: any): allCountries[]; }'.
я понимаю, что ошибка связана с тем, что «фильтр» доступен для простых массивов, а не для массивов объектов.
Я не публиковал весь код, потому что это было бы бесполезно, поскольку не связано с моей проблемой.
Спасибо за помощь
Комментарии:
1. где вы устанавливаете значение
this.allCountries
? Поместите точку останова в строку, в которой вы это делаетеthis.allCountries = ...
, и, скорее всего, вы увидите, что это не массив, который присваивается этой переменной.2. allCountries=allCountries[ ], практически я присваиваю значение этой переменной преобразователю json, поступающего из веб-сервиса. проблема в том, что filter или also sort применимы только к массиву
Ответ №1:
Проблема здесь в том, что Array.filter
это функция, а не свойство. Поэтому он не может быть назначен таким образом : this.allCountries.filter =
.
Вместо этого его следует вызывать как функцию, передавая в качестве аргумента другую функцию, которая будет выполнять фильтрацию.
Пример фильтрации для стран, в названии которых есть введенная подстрока (функция String.includes()
:
this.filteredCountries = this.allCountries.filter(
obj => obj.name.toLowerCase().includes(filterValue.trim().toLowerCase())
);
Хорошей идеей будет сохранить два отдельных массива, один неизменяемый со всеми странами ( allCountries
), а другой с заданными отфильтрованными странами в соответствии с введенным текстом (например: filteredCountries
). В противном случае каждый цикл фильтрации будет уменьшать массив, и в конечном итоге массив стран будет пустым.
Это общая идея:
export class AppComponent {
allCountries = [
{
name: "England"
},
{
name: "France"
}
];
filteredCountries = [];
ngOnInit() {
this.filteredCountries = this.allCountries;
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
if (!filterValue) {
//empty filter, show all countries:
this.filteredCountries = this.allCountries;
} else {
console.log("Filtering for " filterValue);
this.filteredCountries = this.allCountries.filter(
obj => obj.name.toLowerCase().includes(filterValue.trim().toLowerCase())
);
}
}
}
И в html вместо allCountries
одного следует привязать к filteredCountries
:
<table mat-table [dataSource]="filteredCountries">
<!-- code omitted for brevity -->
</table>
Вот stackblitz с рабочим кодом:
https://stackblitz.com/edit/angular-ivy-lzkxnr?file=src/app/app.component.ts
Комментарии:
1. Большое тебе спасибо, брат, ты сэкономил мне много времени <3