首页 > 解决方案 > 如何使用 Angular8 将焦点设置在具有动态生成的元素 ID 的材质输入上

问题描述

我有一个带有许多动态生成输入的 GUI。

我可以像这样分配输入动态生成的ID:

<ul>
  <li *ngFor="#item of items" >
    <mat-form-field>
      <input type=number attr.id={{item.name}}}
    </mat-form-field>
  </li>
</ul>

我希望能够将焦点设置在具有动态名称的特定输入上。这可能吗?

因为 id 是动态生成的,所以我们不能像这样使用 @viewchild 方法:

@ViewChild('usernameField') usernameField: ElementRef;

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

在材料文档中提到了焦点方法和 FocusOptions,但没有示例:

https://material.angular.io/components/input/overview

标签: angularangular-material

解决方案


您可以使用模板逻辑根据条件(例如,id 是某个值)应用模板引用变量,然后允许使用 ViewChild。

如果您还不知道要关注的元素的 id,并且 id 是动态生成的 - 而不是随机生成的,那么它很可能是可预测的。换句话说,您可以预先确定您想要关注的组件的 id。

最简单的情况是当您知道 id 是什么时,但也有可能是 id 以外的其他东西决定了焦点,例如顺序或位置。这是一个如何将焦点应用于 NgFor 列表中的最后一个元素的示例:

<ul>
  <li *ngFor="let item of items; last as isLast" >
    <mat-form-field>
      <input *ngIf="isLast; else noFocus" #usernameField type=number attr.id={{item.name}}>
    </mat-form-field>
  </li>
</ul>
<ng-template #noFocus>
  <input type=number attr.id={{item.name}}>
</ng-template>

@ViewChild('usernameField') usernameField: ElementRef;

ngAfterViewInit() {
  setTimeout(() => this.usernameField.nativeElement.focus());
}

当然,NgIf 中使用的表达式可以是任何东西,包括简单的值比较,例如:

<input *ngIf="item.name === 'usernameField'; else noFocus" #usernameField type=number attr.id={{item.name}}>

推荐阅读