聚焦克隆元素

Focus the cloned element

我有一个 ng-template,只要单击一个按钮,它就会被克隆。在 ng-template 中有一个具有属性 autofocus 的输入字段。我想要的是关注将被克隆的输入字段。我该怎么做?

我已经用 this.email.nativeElement.focus(); 试过了,但我得到了错误:

Cannot read property 'nativeElement' of undefined

HTML:

<form id="add-user">
    <ng-template #emailTmpl>
        <mat-form-field class="email full-width">
            <input autofocus #email matInput class="email-field" type="email" required placeholder="E-Mail">
        </mat-form-field>
    </ng-template>
    <div #furtherEmails></div>
</form>
<i class="material-icons icon" id="addEmailField" (click)="clone()">add_box</i>

<button mat-raised-button class="full-width" color="primary">Invite</button>

TS:

import {Component, OnInit, ViewChild, ViewContainerRef} from '@angular/core';

@Component({
  selector: 'app-add-user',
  templateUrl: './add-user.component.html',
  styleUrls: ['./add-user.component.sass']
})

export class AddUserComponent implements OnInit {
    @ViewChild('emailTmpl') emailTmpl;
    @ViewChild('email') email;
    @ViewChild('furtherEmails', {read: ViewContainerRef}) furtherEmails;

    public clone(): void {
        this.furtherEmails.createEmbeddedView(this.emailTmpl);
        this.email.nativeElement.focus();
    }

    ngOnInit() {
        this.clone();
    }
}

在大多数情况下,在 AfterViewInit 生命周期挂钩之前无法访问 ViewChild 属性。尝试实施 AfterViewInit 并在那里添加您的焦点声明。

元素在 ngOnInit 时尚未创建,因此此时 nativeElement 为空。

这是我的一个应用程序中的一些示例代码:

import { Component, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'pm-criteria',
  templateUrl: './criteria.component.html',
  styleUrls: ['./criteria.component.css']
})
export class CriteriaComponent implements AfterViewInit {

  @ViewChild('filterElement') filterElementRef: ElementRef;

  constructor() { }

  ngAfterViewInit(): void {
    if (this.filterElementRef.nativeElement) {
      this.filterElementRef.nativeElement.focus();
    }
  }

}

您会收到通知,通过订阅 QueryList.changes 事件创建了一个新的 input 元素,其中 QueryList<ElementRef> 是通过 ViewChildren 获得的。每次触发事件时,您都可以关注列表的最后一个元素。有关演示,请参阅 this stackblitz

import { Component, ViewChild, ViewContainerRef, ElementRef, AfterViewInit, ViewChildren, QueryList } from '@angular/core';
...

export class AppComponent {
  @ViewChild('emailTmpl') emailTmpl;
  @ViewChild('furtherEmails', { read: ViewContainerRef }) furtherEmails;
  @ViewChildren('email') email: QueryList<ElementRef>;

  public clone(): void {
    this.furtherEmails.createEmbeddedView(this.emailTmpl);
  }

  ngAfterViewInit() {
    this.email.changes.subscribe(() => {
      this.email.last.nativeElement.focus();
    });
  }
}