【问题标题】:Mat Auto Complete does not open dropdown panel after clicking Clear button单击清除按钮后,垫自动完成未打开下拉面板
【发布时间】:2021-06-16 14:14:04
【问题描述】:

我在 Angular 项目中有自定义 Mat Auto Complete。它有 2 个后缀,清除和下拉按钮。当我单击清除按钮代码this.myControl.reset('', { emitEvent: true }); 时重置输入值。但是下拉面板没有打开。我尝试使用以下格式,但没有任何效果

  1. this.myControl.reset();
  2. this.myControl.reset('', { emitEvent: true });
  3. this.myControl.patchValue('');

StackBlitz Demo

autocomplete-display-example.ts

.......

 clearInput() {
    this.arrowIcon = "arrow_drop_down";
    this.myControl.reset('', { emitEvent: true });
  }

......

autocomplete-display-example.html

<form class="example-form">
 <mat-form-field class="example-full-width">
   <mat-label>Assignee</mat-label>
   <input
     type="text"
     matInput
     [formControl]="myControl"
     [matAutocomplete]="auto"

   />
   <div matSuffix style="display:flex">
     <button
       *ngIf="myControl!==undefined && myControl.value!==null && myControl?.value!==''"
       mat-icon-button
       aria-label="Clear"
       (click)="clearInput()"
       type="button"
     >
       <mat-icon>clear</mat-icon>
     </button>

     <button mat-icon-button aria-label="Clear" type="button">
       <mat-icon>{{arrowIcon}}</mat-icon>
     </button>
   </div>

   <mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn" (opened)="arrowIcon='arrow_drop_up'"
     (closed)="arrowIcon='arrow_drop_down'" (optionSelected)="arrowIcon='arrow_drop_down'">
     <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
       {{option.name}}
     </mat-option>
   </mat-autocomplete>
 </mat-form-field>
</form>

<!-- Copyright 2020 Google LLC. All Rights Reserved.
   Use of this source code is governed by an MIT-style license that
   can be found in the LICENSE file at http://angular.io/license -->

【问题讨论】:

    标签: angular angular-components angular11 mat-autocomplete


    【解决方案1】:

    好的,当我单击清除图标时,它会重置表单控件并关闭面板。为了解决这个问题,我们可以手动打开面板。将MatAutocompleteTriggerevent一起注入到方法中

    查看更新后的StackBlitz Demo

      openPanel(evt: any, trigger: MatAutocompleteTrigger): void {
        evt.stopPropagation();
        this.myControl?.reset();
        trigger.openPanel();
        this.inputAutoComplete?.nativeElement.focus();
      }
    

    #trigger="matAutocompleteTrigger" 添加到输入并将其传递给按钮click() 方法

    autocomplete-display-example.html

    
    <form class="example-form">
      <mat-form-field class="example-full-width">
        <mat-label>Assignee</mat-label>
        <input #inputAutoComplete
               [formControl]="myControl"
               [matAutocomplete]="auto"
               #trigger="matAutocompleteTrigger"
               matInput
               type="text"
        />
    
        <div matSuffix style="display:flex">
          <button
            (click)="openPanel($event, trigger)"
            *ngIf=" myControl?.value!==null && myControl?.value!==''"
            aria-label="Clear"
            mat-icon-button
            type="button"
          >
            <mat-icon>clear</mat-icon>
          </button>
    
          <button aria-label="Clear" mat-icon-button type="button">
            <mat-icon>{{arrowIconSubject.getValue()}}</mat-icon>
          </button>
        </div>
    
        <mat-autocomplete #auto="matAutocomplete" (closed)="arrowIconSubject.next('arrow_drop_down')"
          (opened)="arrowIconSubject.next('arrow_drop_up')" (optionSelected)="arrowIconSubject.next('arrow_drop_down')"
          [displayWith]="displayFn">
          <mat-option *ngFor="let option of filteredOptions | async " [value]="option">
            {{option.name}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
    </form>
    

    【讨论】:

    • 您的 StackBlitz 救了我,这是我尝试解决了 8-10 小时的问题!!你是我本周的英雄:)
    • @Itay 很高兴它对您有所帮助。还是不知道为什么官方材质组件不支持这样的基本功能
    • 顺便说一句,如果我删除 evt.stopPropagation(); 并将 focus()openPane() 放在 setTimout 中,零秒它也可以工作......这很有趣。
    • requestAnimationFrame 而不是 setTimeout() 也会这样做:)
    • @Itay 因为我需要在多个项目中使用它,所以我为此创建了新库。你可以在这里看到它npmjs.com/package/@ngxsmart/autocomplete
    【解决方案2】:

    收到日期后调用过滤函数。如果数据是本地数据,则在声明日期后调用过滤器函数,如果数据来自 Rest api,则在成功响应后调用过滤器函数像这样

    private getAllCategories() {
    this.categoryService.getCategory("").subscribe(
         (response) => {
             if (response) {
                 this.categories = response['rows'];
    
    
                //Now callling category filter after data is received
    
                this.filteredCategories = this.category.valueChanges
                .pipe(
                startWith(''),
                map(state => state ? this._filterCateg(state) : this.categories?.slice())
                );
             }
         },
         (error) => {
             console.info('error:', error);
                 }
     );
    }
    

    它对我有用!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-10
      • 2018-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-22
      • 2011-02-10
      相关资源
      最近更新 更多