如何关注Angular中的输入

时间:2018-04-19 18:14:14

标签: angular typescript

这应该很简单,但我找不到解决方案,我在SO上找到的最接近的答案是:How do I programmatically set focus to dynamically created FormControl in Angular2

然而,这更符合我的要求。我很简单。我在模板中有一个输入:

<div *ngIf="someValue">    
    <input class="form-control" #swiper formControlName="swipe" placeholder="Swipe">
</div>

(注意,它是在一个ngx-boostrap表单控制组中,但我很确定这不重要)

我有一个按钮,当点击时调用以下功能:

onClick() {
    this.renderer.invokeElementMethod(this.swiper.nativeElement, 'focus')
}

目标是单击按钮时,我的输入元素将获得焦点。这是我的组件的其余部分(相关部分):

import { Component, ElementRef, ViewChildren, Renderer } from '@angular/core';
import { MyService } from wherever/my/service/is

export class MyClass {
    @ViewChildren('swiper') input: ElementRef;
    someValue: any = false;

    constructor(private renderer: Renderer, service: MyService) {
       this.service.getSomeData().subscribe(data => {
          this.someValue = true;
       }
    }

    onClick() {
        this.renderer.invokeElementMethod(this.swiper.nativeElement, 'focus');
    }
}

我得到的错误是:

ERROR TypeError: Cannot read property 'focus' of undefined
at RendererAdapter.invokeElementMethod (core.js:12032)
etc...

有什么想法吗?

(Angular 5 btw)

注意,我编辑了代码以更准确地反映实际发生的情况,我认为可能存在一些同步问题。

6 个答案:

答案 0 :(得分:5)

您正在使用ViewChildren返回QueryList您需要使用ViewChild并且您的代码应该有效。

export class MyClass {
    @ViewChild('swiper') swiper: ElementRef;

    constructor(private renderer: Renderer) {}

    onClick() {
        this.swiper.nativeElement.focus();
    }
}

答案 1 :(得分:3)

这就是我解决它的方法:

模板:

<input class="form-control" #swiper formControlName="swipe" placeholder="Swipe">

组件:

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

export class MyClass {
    @ViewChild('swiper') swiper: ElementRef;

    constructor() {}

    onClick() {
        this.swiper.nativeElement.focus();
    }
}

关键是两件事:首先使用ViewChild而不是ViewChildren(感谢@Teddy Stern),然后根本不需要使用Renderer,只需直接使用nativeElement的焦点功能。 / p>

答案 2 :(得分:3)

如果您有输入和按钮

<input #myinput>
<button (click)="myinput.focus()">click</button>

答案 3 :(得分:0)

添加cdkFocusInitial指令对我有用:

<input
    matInput
    cdkFocusInitial />

答案 4 :(得分:0)

如果有兴趣的人将注意力放在动态生成的元素上,#name不可能保留在该字段中作为属性。我找到了使用本机JS的方法。

<textarea [(ngModel)]="update.newComment"
          [name]="'update-' + index" 
          placeholder="comment"></textarea>

现在,专注于textarea以上的触发条件就像

<span (click)="focusOn(index);">Comment</span>

点击事件将在ts中作为

处理
focusOn(fieldName) {
    const commmentBoxes = document.querySelectorAll(`textarea[ng-reflect-name="update-${fieldName}"]`);
    for( let i in commmentBoxes) {
        const element: any = commmentBoxes[i];
        const attributs = element.attributes;
        for(let j in attributs) {
            const attribute = attributs[j];
            if (attribute.nodeName === 'ng-reflect-name' && attribute.nodeValue === `update-${fieldName}`) {
                element.focus();
            }

        }

    }

}

答案 5 :(得分:0)

有时您可以在html中使用属性autofocus ...