如何通过绑定设置焦点元素?

时间:2016-07-11 12:34:21

标签: angular

在Angular2中如何设置元素焦点的绑定。 我不想用elementRef设置它。 我认为在AngularJS中有ngFocus指令 在Angular2中没有这样的指令

9 个答案:

答案 0 :(得分:15)

渲染器服务现在是deprecated(自Angular 4.x起) 新的Renderer2服务没有invokeElementMethod。 你可以做的是获得这样的元素的引用:

const element = this.renderer.selectRootElement('#elementId');

然后您可以使用它来关注该元素,如下所示:

element.focus();

有关selectRootElement如何运作的详情here

编辑:

如果元素没有聚焦,常见的问题是元素没有准备好。 (例如:禁用,隐藏等)。你可以这样做:

setTimeout(() => element.focus(), 0);

这将创建一个将在下一个VM转弯中运行的macrotask,因此如果启用该元素,焦点将正常运行。

答案 1 :(得分:14)

一个简单的“焦点”指令

import {Directive, Input, ElementRef} from 'angular2/core';
@Directive({
    selector: '[focus]'
})
class FocusDirective {
    @Input()
    focus:boolean;
    constructor(@Inject(ElementRef) private element: ElementRef) {}
    protected ngOnChanges() {
        this.element.nativeElement.focus();
    }
}

// Usage
@Component({
    selector : 'app',
    template : `
        <input [focus]="inputFocused" type="text">
        <button (click)="moveFocus()">Move Focus</button>
    `,
    directives: [FocusDirective]
})
export class App {
    private inputFocused = false;
    moveFocus() {
        this.inputFocused = true;
        // we need this because nothing will 
        // happens on next method call, 
        // ngOnChanges in directive is only called if value is changed,
        // so we have to reset this value in async way,
        // this is ugly but works
        setTimeout(() => {this.inputFocused = false});
    }
}

答案 2 :(得分:8)

我尝试了两种变体,但没有一种适合简单使用。 1st(由@AngJobs)在组件中需要额外的工作,你使用指令(设置focus = true),第二个(由@ShellZero)完全不工作,因为在视图实际准备好之前调用的焦点。所以我将焦点调用移到了ngAfterViewInit。现在你可以添加<input focus...并忘掉它。元素将在视图初始化后自动获得焦点。

import { Directive, ElementRef, Renderer, AfterViewInit } from '@angular/core';
@Directive({
    selector: '[focus]'
})

export class DmFocusDirective implements AfterViewInit {
    constructor(private _el: ElementRef, private renderer: Renderer) {
    }

    ngAfterViewInit() {
        this.renderer.invokeElementMethod(this._el.nativeElement, 'focus');
    }
}

答案 3 :(得分:2)

使用angular2设置焦点的最佳方法是使用Renderer并在元素上调用方法。没有elementRef,就无法做到这一点。

这导致如下:

this.renderer.invokeElementMethod(this.input.nativeElement, 'focus', []);

使用renderer

在构造函数中注入protected renderer : Renderer的位置

答案 4 :(得分:1)

更简单的方法:

<name> (<%val>): <data>

答案 5 :(得分:1)

它适用于我,但在控制台中有错误。 经过调试和搜索后发现了这篇文章:https://www.picnet.com.au/blogs/guido/post/2016/09/20/angular2-ng2-focus-directive/

只需复制粘贴即可。它对我来说很完美。

import {Directive, AfterViewInit, ElementRef, DoCheck} from '@angular/core';

@Directive({selector: '[focus]'})
export class FocusDirective implements AfterViewInit, DoCheck {
    private lastVisible: boolean = false;
    private initialised: boolean = false;

    constructor(private el: ElementRef) {
    }

    ngAfterViewInit() {
        console.log('inside FocusDirective.ngAfterViewInit()');
        this.initialised = true;
        this.ngDoCheck();
    }

    ngDoCheck() {

        console.log('inside FocusDirective.ngDoCheck()');

        if (!this.initialised) {
            return;
        }
        const visible = !!this.el.nativeElement.offsetParent;
        if (visible && !this.lastVisible) {
            setTimeout(() => {
                this.el.nativeElement.focus();
            }, 1);
        }
        this.lastVisible = visible;
    }
}

答案 6 :(得分:0)

import { Directive, ElementRef, AfterViewChecked } from '@angular/core';

@Directive({
 selector: '[autoFocus]',
})
export class FocusDirective implements AfterViewChecked {

  constructor(private _elementRef: ElementRef) { }

  ngAfterViewChecked() {
    this._elementRef.nativeElement.focus()
  }

}

答案 7 :(得分:0)

我从@MrBlaise中获取了setTimeout片段,它为我完成了以下工作。

<input type="text" #searchInput />



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

...

@ViewChild('searchInput') private searchInput: ElementRef;

...

setTimeout(() => this.searchInput.nativeElement.focus(), 0);

答案 8 :(得分:0)

技巧是同时使用焦点和一起选择:

this.(element).nativeElement.focus();
this.(element).nativeElement.select();