关注克隆的元素

时间:2018-07-23 23:27:25

标签: angular angular6

我有一个ng-template,只要单击按钮,它就会被克隆。在ng-template中,有一个输入字段,其属性为autofocus。我想要的是将要克隆的输入字段作为焦点。我该怎么办?

我用this.email.nativeElement.focus();尝试过,但收到错误消息:

  

无法读取未定义的属性'nativeElement'

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();
    }
}

2 个答案:

答案 0 :(得分:1)

在大多数情况下,只有在AfterViewInit生命周期挂钩之后才能访问ViewChild属性。尝试实现AfterViewInit并在其中添加焦点声明。

在ngOnInit时尚未创建元素,因此那时的nativeElement为null。

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

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();
    }
  }

}

答案 1 :(得分:1)

您可以通过订阅input事件(其中使用QueryList.changes获取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();
    });
  }
}