如何实现根据以下 Angular Material 筹码输入字段中的输入文本进行过滤的下拉菜单? ( Angular 反应形式)

How do I implement a dropdown which will filter according to input text in the following Angular Material Chips input field? ( Angular reactive form)

我想在以下代码中实现一个自动完成功能或至少一个带过滤选项的下拉菜单。 IE。当输入字段为空时,可以显示数组对象名称 属性 中的所有选项,并且当用户键入内容时,需要根据输入文本过滤下拉选项。我是 Angular material 的新手,在 stackblitz 上看到了这个代码示例。

HTML代码:

    <form class="flex col" (ngSubmit)="onSubmit()" [formGroup]="registerForm">
    <mat-form-field class="chip-container">
        <mat-chip-list #chipList formArrayName="Tags">
            <mat-chip *ngFor="let tag of tagsArr.controls; let i = index" [removable]="true" (removed)="onRemove(i, tag)" [formGroupName]="i">
                {{tag.get('Text').value}}
        <mat-icon matChipRemove>cancel</mat-icon>
      </mat-chip>
      <!-- Use below if only having single formcontrol -->
      <!-- <mat-chip *ngFor="let tag of tagsArr.controls; let i = index" [removable]="true" (removed)="onRemove(i)">
                {{tag.value}}
        <mat-icon matChipRemove>cancel</mat-icon>
      </mat-chip> -->
    </mat-chip-list>
  </mat-form-field>

  <mat-chip-list>
    <mat-chip *ngFor="let tag of tags" [selectable]="selectable" (click)="onSelect(tag)">
    {{tag.Text}}
    </mat-chip>
    </mat-chip-list>
    <button type="submit">Submit</button>
    </form>

TS 文件:

 registerForm: FormGroup;


selected = [];

  tags = [{ Text: 'one' }, { Text: 'two' }];

  constructor(private fb: FormBuilder) {
    this.registerForm = this.fb.group({
      Tags: this.fb.array([]),
    });
  }

  get tagsArr() {
    return this.registerForm.get('Tags') as FormArray;
  }

  onSelect(tag: any) {
    this.tagsArr.push(
      this.fb.group({
        Text: tag.Text,
      })
    );
    this.tags.splice(this.tags.indexOf(tag), 1);
  }

  onRemove(index, tag): void {
    this.tagsArr.removeAt(index);
    this.tags.push(tag.value);
  }

  onSubmit(){
    console.log(this.registerForm.value)
  }
}

这里是你如何使用自动完成实现芯片输入

HTML:

  <form [formGroup]="myForm">
    <mat-form-field>
      <mat-label translate>Tags</mat-label>
      <mat-chip-list #chipList>
        <mat-chip *ngFor="let tag of tags" (removed)="remove(tag)" color="accent">
          {{tag}}
          <button matChipRemove>
            <mat-icon>cancel</mat-icon>
          </button>
        </mat-chip>
        <input placeholder="New tag ..." #tagInput
          [formControl]="tagControl"
          [matAutocomplete]="auto"
          [matChipInputFor]="chipList"
          (matChipInputTokenEnd)="add($event)"
          matChipInputAddOnBlur>
      </mat-chip-list>
      <mat-autocomplete #auto="matAutocomplete" (optionSelected)="selected($event)">
        <mat-option *ngFor="let tag of filteredTags | async" [value]="tag">
          {{tag}}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
  </form>

TS:

  myForm: FormGroup
  filteredTags: Observable<string[]>
  allTags: string[] = []
  tags: string[] = []

  @ViewChild('tagInput') tagInput: ElementRef<HTMLInputElement> | undefined = undefined

  constructor(
    private fb: FormBuilder
  ) {
    this.myForm= this.fb.group({
      tags: ['']
    })

    this.filteredTags = this.tagControl.valueChanges.pipe(
      startWith(null),
      map(tag => tag ? this.filter(tag): this.allTags.slice())
    )
  }

  ngOnInit(): void {
    this.allTags = ['concert', 'restaurant', 'pub']
  }

  // TAG AUTOCOMPLETE CONTROL
  get tagControl(): FormControl {
    return this.myForm.get('tags') as FormControl
  }

  remove(tag: string): void {
    const index = this.tags.indexOf(tag)

    if (index >= 0) {
      this.tags.splice(index, 1)
    }
  }

  add(event: MatChipInputEvent): void {
    const value = (event.value || '').trim()
    if (value) {
      this.tags.push(value)
    }

    event.chipInput?.clear()
    this.tagControl.setValue(null)
  }

  selected(event: MatAutocompleteSelectedEvent): void {
    this.tags.push(event.option.viewValue)
    if (this.tagInput) {
      this.tagInput.nativeElement.value = ''
    }
    this.tagControl.setValue(null)
  }

  private filter(value: string): string[] {
    const filterValue = value.toLowerCase()

    return this.allTags.filter(tag => tag.toLowerCase().includes(filterValue))
  }