Подключение динамически генерируемого поля ввода к mat-autocomplete
Я разрешаю пользователям динамически создавать поля ввода. Для каждого из этих полей ввода я хочу подключить его к отдельному мат-автозаполнению, чтобы они работали независимо друг от друга. Я столкнулся с кирпичной стеной, потому что не могу динамически создать ссылку на элемент (#auto здесь), которая соединяет автозаполнение с вводом. Как мне этого добиться?
<div
class="row"
*ngFor="let field of getControls('requestFields'); let i = index"
formArrayName="requestFields"
>
<ng-container [formGroupName]="i">
<div class="col-md-4">
<mat-form-field class="example-full-width">
<input
type="text"
placeholder="Name"
matInput
formControlName="reqName"
matAutocomplete="auto"
/>
<mat-autocomplete #auto="matAutocomplete">
<mat-option
*ngFor="let option of (filteredColumns | async)"
[value]="option"
>
{{ option }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</div>
<div class="col-md-2">
<div class="togglebutton">
<label>
<span>Optional</span>
<input type="checkbox" formControlName="reqOption" />
<span class="toggle"></span>
</label>
</div>
</div>
<div class="col-md-4">
<mat-form-field>
<input
matInput
formControlName="reqValidations"
placeholder="Validation"
type="text"
/>
</mat-form-field>
</div>
</ng-container>
</div>
1 ответ
Хорошая вещь о mat-autocomplete
является то, что он полностью отделен от mat-form-field
поэтому вы можете поместить его в любое место за пределами динамически генерируемых строк. Итак, на вашем примере - решение может выглядеть так:
<div
class="row"
*ngFor="let field of getControls('requestFields'); let i = index"
formArrayName="requestFields"
>
<ng-container [formGroupName]="i">
<div class="col-md-4">
<mat-form-field class="example-full-width">
<input
type="text"
placeholder="Name"
matInput
formControlName="reqName"
matAutocomplete="auto"
/>
</mat-form-field>
</div>
<!-- other dynamic content -->
</ng-container>
</div>
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredColumns | async" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
Тогда вы могли бы иметь обработчик событий для keyup
на входе, который запускает обновление для filteredColumns
<mat-form-field class="example-full-width">
<input
type="text"
placeholder="Name"
matInput
formControlName="reqName"
matAutocomplete="auto"
(keyup)="reqNameChanged(field.get('reqName')?.value)"
/>
</mat-form-field>
И в вашем компоненте вы можете настроить filteredColumns
наблюдаемый, который запускается субъектом из keyup
обработчик события:
import { Component, OnInit } from '@angular/core';
import { Observable, Subject } from 'rxjs';
import {
debounceTime,
distinctUntilChanged,
filter,
switchMap
} from 'rxjs/operators';
@Component({
selector: 'example',
templateUrl: './example.html',
styleUrls: ['./example.scss']
})
export class ExampleComponent implements OnInit {
filteredColumns: Observable<string[]>;
reqNameSubject: Subject<string> = new Subject<string>();
constructor(private lookup: ILookupService) {}
ngOnInit() {
this.filteredColumns = this.reqNameSubject.pipe(
filter(v => !!v),
debounceTime(300),
distinctUntilChanged(),
switchMap(value =>
/* call for the autocomplete data */
this.lookup.search(value)
)
);
}
reqNameChanged(value: string) {
this.reqNameSubject.next(value);
}
}
Я надеюсь, что это помогает.