选择角度自动完成输入并模糊事件竞争条件

For*_*stG 11 angular-material angular

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

这是很有问题的,因为我需要监听输入字段中的模糊事件进行验证,并观察选择。如果用户单击某个元素,模糊会导致调用该字段上的评估逻辑,这可能会弄乱事情。

<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);
  }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

Tom*_*mba 7

您可以在单击时不应触发模糊事件的项目上使用mousedownevent.preventDefault() 。

<mat-autocomplete #auto="matAutocomplete" (optionSelected)="optionSelected()">
   <mat-option *ngFor="let option of options" (mousedown)=$event.preventDefault()   
         [value]="option"> 
     {{option}}
   </mat-option>
</mat-autocomplete>
Run Code Online (Sandbox Code Playgroud)

  • 对我来说最好的解决方案。当使用键盘选择自动选择项时,它按预期工作,但是当用户使用鼠标时(onblur 按预期执行),上述解决方案会阻止 onblur! (2认同)

For*_*stG 6

我找到了一个不那么hacky的解决方案:

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

  @ViewChild('autocomplete') autocomplete: MatAutocomplete;

  ...
  onBlur(){  if(autocomplete.isOpen){....}   }
Run Code Online (Sandbox Code Playgroud)

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