在Angular2中如何设置元素焦点的绑定。 我不想用elementRef设置它。 我认为在AngularJS中有ngFocus指令 在Angular2中没有这样的指令
答案 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();