Angular Material:当用户点击输入键时隐藏自动完成面板

Posted

技术标签:

【中文标题】Angular Material:当用户点击输入键时隐藏自动完成面板【英文标题】:Angular Material: Hide Autocomplete Panel when User hits enter Key 【发布时间】:2018-07-02 00:56:09 【问题描述】:

我目前正在处理一个表格,用户可以通过按 Enter 键来切换可编辑元素。我也使用了 Angular Material。

我有一个 mat-form-field,其中包含几个使用 mat-autocomplete 元素动态创建的输入字段。但是我的 enter 键事件在这方面有点不同。

当您按下输入字段时,将打开一个面板(下拉菜单),用户可以在其中选择输入,或者他可以简单地自己写,面板会给出建议(自动完成)。

如果按 Tab 键会发生什么?

如果您在键入时按 tab,光标将移动到下一个可编辑元素上,并且最新元素的面板(下拉菜单)将关闭。

如果按下回车键会发生什么

如果您在输入时按下回车键,光标将移动到下一个可编辑元素上,但是最新元素的面板(下拉菜单)保持打开状态,这会导致多个输入字段具有打开的下拉面板,即使用户已经写过他需要什么。

模板:

<tr *ngFor="let row of rows; let rowIdx = index">
            <td *ngFor="let col of columns; let colIdx = index">
                <mat-form-field class="example-full-width">             
                <input  #inputs type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto"
                    (keyup.enter)="shiftFocusEnter(rowIdx, colIdx)">
                    <mat-autocomplete #auto="matAutocomplete">
                            <mat-option *ngFor="let option of filteredOptions | async" [value]="option">
                             option 
                            </mat-option>
                        </mat-autocomplete>
                    </mat-form-field>
            </td>
      </tr>

这只是根据数组中对象的数量创建行(这里不是很重要)。

在输入字段上还有一个 keyup.enter 事件,当用户在焦点位于输入字段时按下 enter 并传递行索引和列索引以获取下一个可编辑元素时,该事件会被触发。

组件:

shiftFocusEnter(rowIdx: number, colIdx: number) 
console.log("Enter", rowIdx, colIdx);  
if(colIdx == 4 && rowIdx == 5) 
  console.log("Reached end of row");

else 
  colIdx = colIdx + this.columns.findIndex(c => c.editable);
  this.autocomplete.showPanel = false;
  this.focusInput(rowIdx, colIdx);

这个函数接收两个参数。行索引和列索引并计算下一个可编辑元素的索引以关注它。

this.autocomplete.showPanel = false 行是为了看看我是否可以像这样简单地关闭面板,但它不起作用。

this.autocompleteMatAutocomplete 类的对象。我已经通过写作添加了这个

@Input('matAutocomplete')
autocomplete: MatAutocomplete

我需要什么:

我希望垫子自动完成元素的下拉面板在按下回车后关闭。

提前致谢!

更新:

所以在工作一段时间后我发现了这个

@ViewChild('test',  read: MatAutocompleteTrigger ) test: MatAutocompleteTrigger;

+

this.test.closePanel();

这次我可以关闭表格中第一个单元格的面板,但是其他输入字段的所有面板都将保持打开状态

【问题讨论】:

你应该使用@Input而不是@ViewChildren 【参考方案1】:

我的用例略有不同,因此您的更新对我不起作用,但我发现了一个略有不同的解决方案可以解决问题:

@ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger;

然后你可以用它来关闭下拉选项:

this.autocomplete.closePanel(); 

确保同时导入 ViewChild:

import  ViewChild  from '@angular/core';

像魅力一样工作。

【讨论】:

如果您在使用材料自动完成的输入上 patchValue 或 setValue,面板将在之后保持打开状态。此解决方案非常适合在更新值后关闭该面板。谢谢!!【参考方案2】:

comment 提供了一个解决方案,您可以直接在输入元素上获取对 ma​​tAutocompleteTrigger 的引用,以便您可以在模板中调用 closePanel()。例如:

    <input
      type="text"
      matInput
      #trigger="matAutocompleteTrigger"
      (keydown.enter)="$event.target.blur(); trigger.closePanel()"
      [formControl]="myControl"
      [matAutocomplete]="auto"
    />

【讨论】:

我完全错过了我需要在代码中引用的触发器。谢谢! (blur)="trigger.closePanel()" 效果很好!但是,如果您有多个自动完成控件,请为每个控件指定不同的触发器名称,即。 #triggerName="matAutocompleteTrigger"#triggerLastname="matAutocompleteTrigger",然后分别添加(blur)="triggerName.closePanel()"(blur)="triggerLastname.closePanel()"【参考方案3】:
// This is my solution  ios/android panel not hide on done button virtual // 


<input type="text" placeholder="lbl.TipDoc"
class="form-control ui-inputtext ui-widget autocomp"
 #trigautoTipDoc ="matAutocompleteTrigger"
 aria-label="name" matInput                                        (blur)="OcuPanelAuto(trigautoTipDoc);"
formControlName="tipDocLbl" [matAutocomplete]="autoTipDoc" >
<mat-autocomplete #autoTipDoc="matAutocomplete" role="combobox">
<mat-option  *ngFor="let option of tipDocFiltObs | async"
                                                            [value]="option.name">
 option.name
</mat-option>
</mat-autocomplete>


OcuPanelAuto(cc: MatAutocompleteTrigger) 
        setTimeout(function a() 
            cc.closePanel();
        , 130);
    

【讨论】:

以上是关于Angular Material:当用户点击输入键时隐藏自动完成面板的主要内容,如果未能解决你的问题,请参考以下文章

Angular Material 输入验证错误消息

Angular2 Material:Angular 材质输入的自定义验证

Angular Material 2 Form 不显示

Angular 材质表 filterPredicate

验证失败时阻止表单提交(Angular Material)

Angular Material Tabs 不适用于包装器组件