为了操纵DOM元素,请始终尝试使用指令。在这种情况下,您可以编写简单的指令。
要从指令访问DOM,我们可以通过指令构造函数中的 ElementRef 注入主机DOM元素的引用。
constructor(@Inject(ElementRef) private element: ElementRef) {}
为了检测所绑定的值的变化,我们可以使用 ngOnChanges 生命周期方法。
protected ngOnChanges() {}
其它的东西都很简单。
简单的解决方案
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();
}
}
@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;
setTimeout(() => {this.inputFocused = false});
}
}
使用EventEmitter解决方案
为了解决 setTimeout(() => {this.inputFocused = false}); 的问题,我们可以将指令绑定到事件源 - EventEmitter 或 Observable。以下是EventEmitter的使用示例。
import {Directive, EventEmitter, Input, ElementRef} from 'angular2/core';
@Directive({
selector: '[focus]'
})
class FocusDirective {
private focusEmitterSubscription;
@Input('focus')
set focus(focusEmitter: EventEmitter) {
if(this.focusEmitterSubscription) {
this.focusEmitterSubscription.unsubscribe();
}
this.focusEmitterSubscription = focusEmitter.subscribe(
(()=> this.element.nativeElement.focus()).bind(this))
}
constructor(@Inject(ElementRef) private element: ElementRef) {}
}
@Component({
selector : 'app',
template : `
<input [focus]="inputFocused" type="text">
<button (click)="moveFocus()">Move Focus</button>
`,
directives: [FocusDirective]
})
class App {
private inputFocused = new EventEmitter();
moveFocus() {
this.inputFocused.emit(null);
}
}
这两个解决方案都可以解决您的问题,但第二个性能略好,并且看起来更漂亮。