【问题标题】:Autocomplete does not show after setValuesetValue 后不显示自动完成
【发布时间】:2018-11-08 01:49:36
【问题描述】:

我正在构建一个使用Angular Material Autocomplete module 的表单。我从服务器加载选项,然后用输入过滤它们。效果很好,现在我想添加一个“清除”图标以在需要时清除该字段。

清除选项会清除该字段,但不会再次显示自动完成选项。当我手动删除带有退格而不是图标的输入内容时,它会显示它们。

要“清除”我使用此代码的字段:

clear(control: string): void {
    this.form.get(control).setValue('');
}

我从 mat-icon 组件调用它:

<mat-form-field>
    <input matInput type="text" ... >
    <mat-icon matSuffix (click)="clear(fieldName)" ...>
        clear</mat-icon>
</mat-form-field>
<mat-autocomplete> ... </mat-autocomplete>

其中 fieldName (string) 是我要清除的控件的名称。

这就是我过滤自动完成选项的方式:

this.filter = this.form.get(field).valueChanges.pipe(
    startWith(''), // Don't even know what this does...
    map(value => this.options.filter(option => option.name.toLowerCase().includes(value.toString().toLowerCase())))
);

我怀疑clear() 方法中的setValue('') 可能存在错误。或者可能是我正在使用的过滤方法。

这是 StackBlitz 中的完整示例:

https://stackblitz.com/edit/angular-autocomplete-clear9zzmw2

【问题讨论】:

  • 我看到即使在我使用清除按钮后,选择仍然显示选项,但我需要取消对选择的关注,然后再次关注它;您想在单击清除按钮后立即显示选项吗?

标签: angular angular-material


【解决方案1】:

您似乎想在单击清除按钮后立即打开选项面板。这不会发生,因为一旦您选择了matAutocomplete 选项,它就会选择该值并关闭选项面板。为了再次打开它,您必须从文本框中删除字符键入匹配的字符序列

这里是手动清除值,但不提示matAutoComplete打开面板。如果查看matAutocomplete 的源代码,您会发现input/blur/keydown 事件发生负责打开和关闭面板。您可以通过手动触发这些事件来做到这一点(进入单独的变更检测周期)。但最方便的方法是调用matAutocompleteopenPanel 方法。

所以让我们专注于如何调用matAutocompleteopenPanel 方法。由于您已将matAutocompletematInput 组合使用,因此它确实导出为matAutocompleteTrigger。因此,在 matInput 元素中添加 #automcomplete="matAutocompleteTrigger",如下所示。

标记

<input
  matInput
  type="text"
  #automcomplete="matAutocompleteTrigger"
  placeholder="Select something"
  formControlName="autocomplete"
  [matAutocomplete]="autocompleteStuff"
  required>

现在使用ViewChild装饰器我们可以查询autocomplete模板变量

组件

// It will have an autocomplete component instance
@ViewChild('automcomplete') autocomplete;
//...
//...
clear(control: string): void {
    this.form.get(control).setValue('');
    // call autoComplete `openPanel` to show up options
    setTimeout(()=> {this.autocomplete.openPanel() })
}

Running Demo


替代解决方案可以模糊化并以编程方式专注于输入。同样,只需在matInput 上保留#automcomplete,然后使用ViewChild 查询元素,然后在查询结果的nativeElement 上触发事件。

HTML

<input
  matInput
  type="text"
  #automcomplete
  placeholder="Select something"
  formControlName="autocomplete"
  [matAutocomplete]="autocompleteStuff"
  required>

组件

@ViewChild('automcomplete') autocomplete;
//...
//...
clear(control: string): void {
    this.form.get(control).setValue('');
    setTimeout(()=> {
      this.autocomplete.nativeElement.blur();
      this.autocomplete.nativeElement.focus();
    })
}

Forked Demo

【讨论】:

  • 我正在尝试openPanel() 方法,但我没有使用setTimeout()...谢谢!!
  • @JCAguilera yupe,那是因为它在相同的更改检测周期中无法理解。我试图找到为什么这里需要额外 CD 的答案,但此后我没有时间深入挖掘:(
  • 如果我能花更多时间在这方面,那么肯定会分享更多关于这方面的见解:) 谢谢 :)
  • 一切正常,谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
相关资源
最近更新 更多