【问题标题】:How to make <mat-autocomplete> show when click on input如何在单击输入时显示 <mat-autocomplete>
【发布时间】:2021-02-01 02:13:40
【问题描述】:

我使用链接到 Angular 8 输入的材料自动完成表单

我是 Angular 的新手,我还在学习。 我已经尝试了一些在 stackoverflow 上找到的解决方案但没有成功(例如:Material autocomplete not displaying list on click

这是我的 HTML 页面:

    <mat-form-field>
      <input
        matInput
        type="text"
        placeholder="Equipment"
        aria-label="Number"
        [formControl]="machineControl"
        [formControl]="machineFilter"
        [matAutocomplete]="auto"
        #machineinput
      />
      <mat-autocomplete #auto="matAutocomplete">
        <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
          {{ option }}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>

这是我的 Typescript 页面:

export class DocumentsListComponent implements OnInit {
  machineControl = new FormControl();
  options: string[] = [];
  filteredOptions: Observable<string[]>;

  @ViewChild('machineControl', { static: true }) input: ElementRef;

 constructor(public restApi: DocumentsService) {}

  ngOnInit() {


    this.restApi.getList().then(res => {
      [...]
      for (const docs of this.Document) {
        if (this.options.some(machine => machine === docs.machine)) {
        } else {
          this.options.push(docs.machine);
        }
      }
    });

    this.filteredOptions = this.machineControl.valueChanges.pipe(
      startWith(''),
      map(value => this._filter(value))
    );

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

        return this.options.filter(option => 
        option.toLowerCase().includes(filterValue));
    }

我希望自动完成表单会在输入点击时显示,但我需要输入至少 1 个字符才能显示(删除此字符仍会显示自动完成表单)

【问题讨论】:

  • 这里的例子都不适合你:material.angular.io/components/autocomplete/examples ?
  • @AkberIqbal 我没有看到此页面上的“过滤器自动完成”示例中缺少的内容。
  • 如果你有硬编码的值而不是从你的 rest api 调用,这是否有效?
  • @AkberIqbal 确实有效!如果你知道它为什么会有这样的反应,至少我有一个新的线索要挖掘。编辑:在我输入 1 个字符之前,它似乎没有加载我的选项列表。如果我输入硬编码值,它会起作用,当我输入 1 个字符时,它会显示我来自 API 的值。
  • 你应该可以得到帮助...基本上,下拉列表this.filteredOptions需要在其余api服务调用返回结果后分配

标签: angular angular-material


【解决方案1】:

已修复,感谢@AkberIqbal

我的问题是在我的 API 调用返回结果之前,我的自动完成功能被一个空列表填充。

为了解决这个问题,我在 restApi 调用中分配了我的过滤选项(一开始是因为把它放在最后没有用):

    this.restApi.getList().then(res => {
      this.dataSource = new MatTableDataSource(res);

      this.filteredOptions = this.machineControl.valueChanges.pipe(
        startWith(''),
        map(value => this._filter(value))
      );

      [...]

      for (const docs of this.Document) {
        if (this.options.some(machine => machine === docs.machine)) {
        } else {
          this.options.push(docs.machine);
        }
      }
    });

再次感谢@AkberIqbal,我为此工作了太长时间,您很快就帮助了我。

【讨论】:

    【解决方案2】:

    由于我遇到了同样的问题并且没有列出此解决方案,我将发布我的解决方案。 对我来说,在从 API 接收到数据后,用空字符串修补输入的值就足够了。

    在你的情况下添加

    this.restApi.getList().then(res => {
      [...]
      this.machineControl.pachValue('') // add this line
    });
    

    【讨论】:

      【解决方案3】:

      另一种方法是移除 HTML 中的异步函数,并将过滤选项的类型从 Observable 更改为数组:

        form: FormGroup;
        code = new FormControl();
        options: Permission[];
        filteredOptions: Permission[];
      
        constructor(
          private dialogRef: MatDialogRef<SelectModalComponent>,
          private formBuilder: FormBuilder,
          private api: DynamicService,
        ) {
          this.form = this.formBuilder.group({
            code: [null, [Validators.required]]
          });
      
          this.api.getAll('/api/permission', null).subscribe((permissions: Permission[]) => {
            this.options = permissions;
            this.filteredOptions = permissions;
            console.log(this.options);
          });
        }
      
        ngOnInit() {
          this.code.valueChanges
            .pipe(
              startWith(''),
              map(value => this._filter(value))
            ).subscribe(ret => {
              this.filteredOptions = ret;
            });
        }
      
        private _filter(value: any): Permission[] {
          if (this.options && typeof (value) === 'string') {
            return this.options.filter(option => option.code.toString().toLowerCase().includes(value.toLowerCase()));
          }
        }
      <form [formGroup]="form" class="example-form" (ngSubmit)="submitForm()">
      
        <div fxLayoutAlign="center center" fxLayout="column">
      
          <mat-form-field class="example-full-width">
            <input type="text" placeholder="Permissões" matInput [formControl]="code" [matAutocomplete]="auto" required>
      
            <mat-autocomplete #auto="matAutocomplete">
              <mat-option *ngFor="let option of filteredOptions" [value]="option.code">
                {{option.code}}
              </mat-option>
            </mat-autocomplete>
      
          </mat-form-field>
      
          <button color="primary" mat-raised-button fxAlign>Salvar</button>
        </div>
      
      
      </form>

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-08-16
        • 1970-01-01
        • 2020-12-07
        • 1970-01-01
        • 1970-01-01
        • 2019-06-16
        • 2020-03-21
        相关资源
        最近更新 更多