*ngIf 带有焦点指令
*ngIf with focus directive
在我的应用程序中,我尝试放置一个按钮,该按钮 shows/hides 一个带有 boolean
组件 属性 的 input
字段。如果按钮显示 input
,则应将焦点设置在 input
上。但它似乎不起作用。如果我删除 *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', []);
});
}
}
EventEmitter
s 适用于 @Output
s,不适用于 @Input
s。尝试这样的事情:
@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', []);
}
}
}
无需使用指令即可实现此目的的更简洁方法是使用 <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.
大多数情况下,它不起作用,因为焦点事件之后有其他事件。所以元素失去了焦点。我们需要使用 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);
}
}
}
在我的应用程序中,我尝试放置一个按钮,该按钮 shows/hides 一个带有 boolean
组件 属性 的 input
字段。如果按钮显示 input
,则应将焦点设置在 input
上。但它似乎不起作用。如果我删除 *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', []);
});
}
}
EventEmitter
s 适用于 @Output
s,不适用于 @Input
s。尝试这样的事情:
@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', []);
}
}
}
无需使用指令即可实现此目的的更简洁方法是使用 <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.
大多数情况下,它不起作用,因为焦点事件之后有其他事件。所以元素失去了焦点。我们需要使用 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);
}
}
}