Внедрить данные JSON из API в автозаполнение ввода mat
Я пытаюсь использовать угловой компонент материала "Выделить первый параметр автозаполнения" на входе, который использует данные JSON с сервера API (который уже работает путем извлечения всех данных JSON). Не знаю, где я иду с этим не так.
Я попытался использовать пример Angular Material, но он использует метод жесткого кодирования, когда мне нужны мои данные из API
service.ts
import { Appl } from '../intdets';
export class IntdetsService {
private url = "/assets/IntDet.json";
constructor(private http: HttpClient) { }
getName(): Observable<Appl[]> {
return this.http.get<Appl[]>(this.url);
}
}
intdets.ts
export class Appl {
_NAME: string;
}
JSON
{
"_APPLS": [
{
"_NAME": "some string",
},...]}
component.ts
export class IntdetsComponent implements OnInit {
public apps = [];
testCtrl: FormControl;
filteredTest: Observable<Appl[]>;
constructor(private _intdetsService: IntdetsService) {
this.testCtrl = new FormControl();
this.filteredTest = this.testCtrl.valueChanges
.pipe(
startWith(null),
switchMap(val => { return this.filterTest(val || '' )}));
}
filterTest(val: string) {
return this._intdetsService.getName().pipe(
map(res => res.filter(s => {
return s._NAME.toLowerCase().indexOf(val.toLowerCase()) === 0
}))
)
}
ngOnInit() {
this._intdetsService.getName()
.subscribe(data => {
this.apps = data;
console.log(data);
});
}
}
HTML
<mat-form-field >
<mat-label>Test Name</mat-label>
<input type="text" matInput [formControl]="testCtrl" [matAutocomplete]="autoTest">
<mat-autocomplete autoActiveFirstOption #autoTest="matAutocomplete">
<mat-option *ngFor="let test of filteredTest | async" [value]="test._APPLS">
{{test._NAME}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</p>
1 ответ
Массив, который вы хотите, находится внутри _APPLS
так что вам нужно извлечь это:
getName(): Observable<Appl[]> {
return this.http.get<any>(this.url).pipe(
map(data => data._APPL as Appl[])
)
}
Я также хотел бы предложить, чтобы в сервисе вы сохраняли ответ в переменной после первого извлечения. Мы не хотим перегружать API, выбирая данные при каждом нажатии клавиши. Вы могли бы сделать как:
data = <Appl[]>[];
getName(): Observable<Appl[]> {
return this.data.length
? of(this.data)
: this.http.get<any>(this.url).pipe(
map(data => {
this.data = data._APPL as Appl[]
return this.data;
})
)
}
Вы также можете рассмотреть возможность добавления debounceTime
на вашей форме управления изменениями.