【问题标题】:Angular Autocomplete Input selected and blur event race condition已选择 Angular 自动完成输入并模糊事件竞争条件
【发布时间】:2020-07-22 02:02:44
【问题描述】:

如果你有一个 Angular Material MatAutoInput,并且你监听选项选择事件并监听模糊事件,你可以看到如果你在选择列表中选择一个项目,输入模糊事件也会被调用.

这很成问题,因为我需要在输入字段中监听 blur 事件以进行验证,并且还要观察 select。如果用户点击一个元素,模糊会导致在字段上调用我的评估逻辑,这可能会搞砸。

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input type="text"
           placeholder="Pick one"
           aria-label="Number"
           matInput
           (blur)="onBlur()"
           [formControl]="myControl"
           [matAutocomplete]="auto">
    <mat-autocomplete #auto="matAutocomplete" (optionSelected)="optionSelected()">
      <mat-option *ngFor="let option of options" [value]="option">
        {{option}}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</form>

@Component({
  selector: 'autocomplete-simple-example',
  templateUrl: 'autocomplete-simple-example.html',
  styleUrls: ['autocomplete-simple-example.css'],
})
export class AutocompleteSimpleExample {
  myControl = new FormControl();
  options: string[] = ['One', 'Two', 'Three'];

  optionSelected(){
    console.log("option selected event, value: ", this.myControl.value);

  }

  onBlur(){
    console.log("Blur event, value:",  this.myControl.value);
  }
}

现场演示:https://stackblitz.com/edit/angular-pp3ztn?file=src%2Fapp%2Fautocomplete-simple-example.ts

有没有办法解决这个问题?或者我可以绝对确定事件发生的顺序吗?如果由于任何原因事件会以不同的顺序发生(首先是选择,然后是模糊),它可能会在我更深层次的输入逻辑中搞砸。

我的关闭解决方案是尝试在单击该字段时禁用模糊事件检查,并且仅在选择选项列表本身上的选项或模糊事件时启用模糊检测......这看起来很hacky。此外,发现了一个相同的线程:https://github.com/angular/material/issues/3976,遗憾的是它没有给出任何真正的解决方案。

【问题讨论】:

  • 只要让事件的顺序无关紧要。显然,模糊和选择选项都应该触发验证。
  • 在我的例子中,模糊事件可以过滤选择列表,这将缩小它。所以用户点击一个列表项,blur事件移除选项列表,当他们释放点击时,没有更多的选项可供选择。

标签: angular angular-material


【解决方案1】:

我找到了一个不太老套的解决方案:

只需将此检查放在(blur) 事件处理中:

  @ViewChild('autocomplete') autocomplete: MatAutocomplete;

  ...
  onBlur(){  if(autocomplete.isOpen){....}   }

这样我们可以在用户单击选项列表时区分模糊事件处理,并确保我们在模糊上运行/不运行验证逻辑。

【讨论】:

    【解决方案2】:

    在我的例子中,我需要清除模糊的输入并在选择选项时设置一个单独的值。由于模糊似乎总是发生在 optionSelected 事件之前,因此放置在 (blur) 侦听器内的任何操作都将完全阻止 optionSelected 事件的发生,而无法辨别输入框外的点击与选择选项。我见过的唯一解决方法是将您的(模糊)操作放在时间 > 0 的 setTimeout 内。

    <input matInput (blur)="onBlur()"...
    <mat-autocomplete (optionSelected)="onSelect($event)"...
    

    在你的组件中:

    onBlur() {
        setTimeout(() => {
            //doStuffOnBlur()
        }, 200);
    }
    
    onSelect(event: MatAutocompleteSelectedEvent) {
        //doStuffWithSelectedOption()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 2021-12-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 2014-11-19
      • 1970-01-01
      相关资源
      最近更新 更多