选择下拉选项后,Angular Material Autocomplete可观察会触发额外的时间

Che*_*eam 6 observable angular-material angular

每当我从“材料自动完成”中选择一个选项时,它将对服务器进行额外的HTTP GET调用。选择下拉选项的预期结果应该只是填充输入。

下拉选项是从服务器动态检索的。

HTML

<form class="example-form">
    <mat-form-field class="example-full-width">
      <input type="text" placeholder="search item" aria-label="Item1" matInput [formControl]="searchTerm" [matAutocomplete]="auto1">
      <mat-autocomplete #auto1="matAutocomplete" [displayWith]="displayFn">
        <mat-option *ngFor="let item of searchResult" [value]="item.Id">
          {{ item.Name }}
        </mat-option>
      </mat-autocomplete>
    </mat-form-field>
  </form>
Run Code Online (Sandbox Code Playgroud)

打字稿

    searchTerm : FormControl = new FormControl();

    searchResult = [];
    constructor(private service: AppService){
      this.searchTerm.valueChanges
          .debounceTime(400) 
          .subscribe(data => {
              this.service.search_word(data).subscribe(response =>{
                  this.searchResult = response
              })
Run Code Online (Sandbox Code Playgroud)

其他一切正常。唯一的问题是,当选择“自动完成”选项时,会意外地额外调用服务器。

快速更新:尚未完全解决这个问题。但是,我已将其范围缩小到displayWith。

Tre*_*ent 4

出现您的问题是因为下拉选择更改了表单控件的值searchTerm;从而valueChanges为该表单控件上的可观察对象发出一个事件。

有几种方法可以valueChanges在表单控件上的可观察对象中构建一些逻辑,以忽略这个不需要的 Http GET 请求。

朴素的解决方案

天真的解决方案是存储下拉选项选择值并跳过可观察逻辑(如果selectionValue === searchTerm.value.

var optionSelection; // set this value on selection of a dropdown option
this.searchTerm.valueChanges
  .debounceTime(400) 
  .subscribe(data => {
    if (optionSelection !== searchTerm.value) {
      this.service.search_word(data).subscribe(response =>{
        this.searchResult = response
      })
    }
  })
Run Code Online (Sandbox Code Playgroud)

更好的解决方案

FormControl 类有一个setValue函数,该函数有一个可选参数来指定是否向valueChanges可观察对象发出事件。

setValue(value: any, options: {
    onlySelf?: boolean;
    emitEvent?: boolean;
    emitModelToViewChange?: boolean;
    emitViewToModelChange?: boolean;
} = {}): void
Run Code Online (Sandbox Code Playgroud)

通过更改下拉选项选择以设置 searchTerm 表单控件值setValue,您可以传递可选emitEvent: false参数并停止发出此附加可观察事件。

searchTerm.setValue(dropdownValue, { emitEvent: false });
Run Code Online (Sandbox Code Playgroud)

如果 emitEvent 为 false,则此更改将导致 FormControl 上的 valueChanges 事件不被发出。默认为 true(因为它会影响 updateValueAndValidity)。