Использование углового материала mat-autocomplete без ReactiveForm
Я пытаюсь использовать <mat-autocomplete>
из Angular Material (не AngularJS) без использования реактивной формы. Но все их примеры используют реактивные формы...
Что я пытаюсь сделать:
1. когда что-то набрано в mat-input
, сделать вызов Ajax, чтобы получить список пользователей
2. Отобразите список пользователей в автозаполнении (отобразите имя пользователя), но сохраните пользователя в качестве модели
3. Когда модель изменится, вызовите функцию на мой выбор
Пока я делаю эти сумасшедшие вещи (я говорю сумасшедшие, потому что это кажется многим).
<mat-form-field fxLayout>
<input type="text"
matInput fxFlex="100"
[(ngModel)]="listFilterValue"
(keyup)="memberInputChanged(input.value)"
(change)="memberChanged()"
*ngIf="isAutocompleteNeeded()"
#input
[matAutocomplete]="auto">
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="getMemberAsStr">
<mat-option *ngFor="let member of members | async" [value]="member">
{{ getMemberAsStr(member) }}
</mat-option>
</mat-autocomplete>
На данный момент есть только console.log
в моем JS, чтобы увидеть, что называется, с какой ценностью, поэтому я не разделяю это здесь. Я использую правильные атрибуты, правильную логику?
(members
свойство в моем компоненте - Rxjs BehaviourSubject)
То, что я делаю сейчас, не работает, потому что listFilterValue
никогда не настроен ни на что.
Спасибо за вашу помощь
1 ответ
Вам следует избегать вызова методов в шаблоне, это может привести к сбою вашего браузера, так как они вызываются при каждом обнаружении изменений, см.: * ng Для запуска бесконечного цикла в angular2 Технически это не бесконечный цикл, но вы понимаете, в чем суть:)
Поскольку отсутствие элемента управления формой с автозаполнением не сильно отличается, вы просто заменяете элемент управления формой на переменную, вы можете использовать шаблонно-управляемую форму, если хотите, или вообще не использовать форму. Вот с формой, управляемой шаблоном, хотя:
Демонстрационная версия JSON, используемая в этом примере, выглядит следующим образом:
"value": [
{
"id": 409,
"joke": "some joke here",
"categories": []
}
]
<form #f="ngForm">
<mat-form-field>
<input matInput [matAutocomplete]="auto"
name="joke" #jokeField="ngModel"
[(ngModel)]="currentJoke" (ngModelChange)="doFilter()">
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let joke of jokes | async" [value]="joke.joke">
{{joke.joke}}
</mat-option>
</mat-autocomplete>
</form>
И ваш TS может выглядеть так:
doFilter() {
this.jokes = this.service.getData()
.pipe(
map(jokes => this.filter(jokes.value)),
)
}
filter(values) {
return values.filter(joke =>
// used 'includes' here for demo, you'd want to probably use 'indexOf'
joke.joke.toLowerCase().includes(this.currentJoke))
}