在我的应用程序中,我尝试放置一个显示/隐藏带有布尔组件属性的输入字段的按钮。如果按钮显示输入,则应在输入上设置焦点。但它似乎不起作用。如果我删除*ngIf
焦点指令正常工作。
我创建了一个显示我的意思的plunker。很难描述我的问题"。
组件中的html
<input *ngIf="filterShow.options"
[focus]="filterFocus.options"
[(ngModel)]="filter.options">
<button type="button"
(click)="setShowFilter('options')">
focus
</button>
setShowFilter()函数
private setShowFilter(filter: string) {
this.filterShow[filter] = !this.filterShow[filter];
/* reset filter */
this.filter[filter] = "";
this.filterFocus[filter].emit(true);
}
focus.directive.ts
@Directive({
selector: '[focus]'
})
export class FocusDirective implements OnInit {
@Input('focus') focusEvent: EventEmitter<boolean>;
constructor(private elementRef : ElementRef,
private renderer : Renderer ) { }
ngOnInit() {
this.focusEvent.subscribe(event => {
this.renderer
.invokeElementMethod(this.elementRef.nativeElement, 'focus', []);
});
}
}
答案 0 :(得分:8)
EventEmitters用于输出,不用于输入。尝试这样的事情:
@Directive({
selector: '[focus]'
})
export class FocusDirective implements OnChanges {
@Input('focus') focus: boolean;
constructor(private elementRef : ElementRef,
private renderer : Renderer ) { }
ngOnChanges() {
if (this.focus) {
this.renderer
.invokeElementMethod(this.elementRef.nativeElement, 'focus', []);
}
}
}
答案 1 :(得分:2)
在大多数情况下,它不起作用,因为焦点事件之后是其他事件。因此,元素失去了焦点。我们需要使用setTimeout
才能将其放置在Task Scheduler队列的末尾:
import { Directive, OnChanges, Input, ElementRef } from "@angular/core";
@Directive({
selector: '[focus]'
})
export class FocusDirective implements OnChanges {
@Input('focus') focus: boolean;
constructor(private elementRef : ElementRef) { }
ngOnChanges() {
if (this.focus) {
setTimeout(() => { this.elementRef.nativeElement.focus(); }, 0);
}
}
}
答案 2 :(得分:0)
在不使用指令的情况下实现此目的的更简洁方法是使用<label>
而不是<button>
并使用css将其设置为按钮。例如,
<label for="myInput"></label>
<input id="myInput"></input>
这样即使存在*ngIf
,您也可以获得焦点,因为<input>
现在已绑定到<label>
。 Also, Angular2 documentation website warns about the use of ElementRef
because of the security vulnerability it poses.