Angular 8/9如何以编程方式将焦点设置在MatInput上

问题描述

我有这个小样本项目 https://stackblitz.com/edit/angular-material-input-sample-nonw

要做的是让用户通过单击一个占位符(如图所示)并输入一个单行文本,如图所示,用户单击那里,然后显示MatInput元素,用户可以在其中输入文本。当用户按Enter键时,将保存并显示文本,而不是显示初始占位符;如果用户转到另一个元素,则输入的文本也会被保存。

我使用ngClass隐藏和显示占位符文本或MatInput控件,具体取决于组件的editMode属性

我遇到的问题:

  • 单击占位符文本时,必须再次单击,因此this.inputField.nativeElement.focus();没有做应该做的事。
  • 单击“编辑”按钮时,这是对this.inputField.nativeElement.focus();的简单调用。正如您所看到的,它仅在MatInput处于屏幕上(未隐藏)时才起作用,即,它为用户节省了额外的一次单击,从而实际上开始在输入字段上输入文本。

问题变成了:如何保证当我停止隐藏一个元素(通过[ngClass]中的切换变量显示)时,将焦点设置在该元素上确实可以按预期工作吗?还是可以保证在屏幕上实际显示元素,以便使element.focus起作用。

解决方法

我只是想起了我在使用angular js时曾经使用过的一个技巧,并且看起来它在un angular 2+上也可以使用,基本上是通过超时来让angular更新视图,所以在更改切换变量之后你用这样的0做一个setTimeout

this.editMode = true; // toggle that shows matInput
setTimeout(() => {
  this.inputField.nativeElement.focus(); // now this actually sets the focus
},0)

这是工作项目:https://stackblitz.com/edit/angular-material-input-sample

,

您可以执行以下操作:
在模板文件中:

<input #myname>

在ts文件中,声明您的html元素:

@ViewChild('myname') input;

最后在组件中使用ngAfterViewInit,以等待视图初始化,然后再对html元素执行焦点:

ngAfterViewInit() {
  this.input.nativeElement.focus();
}

编辑:

您可以在<p>元素上设置点击侦听器,然后执行以下方法:
在您的模板中:

<p (click)="focusInput()">

在您的ts文件中:

focusInput() {
  if (input) {
    this.input.nativeElement.focus();
  }
}