将动态生成的输入字段连接到mat-autocomplete

时间:2018-08-02 08:46:34

标签: angular-material angular5 mat-autocomplete

我允许用户动态创建输入字段。对于这些输入字段,我想将其连接到不同的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 个答案:

答案 0 :(得分:0)

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);
  }
}

希望对您有帮助。