angular - Angular Directive 未正确设置最近禁用的输入的焦点
问题描述
我有一个输入字段,当用户按下“输入”键时,我想禁用它。然后它将尝试获取用户详细信息。当它获取详细信息或出现错误时,我想再次启用输入字段并将焦点设置在该字段上。
我正在使用此指令将焦点设置在输入字段上:
import { Directive, OnChanges, ElementRef, Input } from '@angular/core';
@Directive({
selector: '[myFocus]'
})
export class FocusDirective implements OnChanges {
@Input('myFocus') isFocused: boolean;
constructor(private hostElement: ElementRef) { }
ngOnChanges() {
if(this.isFocused) {
this.hostElement.nativeElement.focus();
}
}
}
它在 html 中实现,如下所示:
<input type="text" class="form-control" [(ngModel)]="text"
[myFocus]="isFocused" [disabled]="disableInput"
(keydown)="podcastsKeyDown($event)">
podcastKeyDown() 函数如下所示:
podcastsKeyDown(event) {
if(event.keyCode == 13) {
this.disableInput = true;
this.getUser(this.text).subscribe(account => {
this.disableInput = false;
this.isFocused = true;
});
}
}
当用户帐户成功返回时,我将输入字段设置为启用,这可以正常工作。但是,焦点不会返回到此输入。我曾尝试在重新设置焦点时设置超时,以防万一出现时间问题,但这也不起作用。代码如下所示:
setTimeout(() => {
this.isPodcastNamesFocused = true;
}, 100);
任何想法这里发生了什么以及如何解决它?
提前致谢。
编辑1:准确地说 - 它实际上在使用超时时第一次工作,但对于后续用户条目它不会......
解决方案
我建议以下解决方案。我在本地测试了这段代码。它每次都对我有用。这里的大部分代码用于演示。
指示:
import {Directive, ElementRef, Input} from '@angular/core';
@Directive({
selector: '[myFocus]'
})
export class MyFocusDirective {
// as for me I prefer using setters for properties that have non-trivial logic when being set. They are simple, predictable and robust.
@Input('myFocus')
set isFocused(val: boolean) {
this._isFocused = val;
if (this._isFocused) {
this.hostElement.nativeElement.focus();
}
}
get isFocused(): boolean {
return this._isFocused;
}
_isFocused: boolean;
constructor(private hostElement: ElementRef) { }
}
零件:
import { Component } from '@angular/core';
import {Observable, of, timer} from 'rxjs';
import {map, take} from 'rxjs/operators';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
text = 'app';
isFocused: boolean = true;
isDisabled: boolean = false;
userData: {name: string, age: number} = null;
podcastsKeyDown(event) {
if (event.keyCode === 13) {
this.isFocused = false;
this.isDisabled = true;
// take(1) not to have subscriptions hanging around
this.getUser(this.text).pipe(take(1)).subscribe(account => {
this.isDisabled = false;
this.userData = account;
// timeout first makes DOM to render setting isDisabled to false
// when field is enabled we can make it focused
setTimeout(() => {
this.isFocused = true;
});
});
}
}
// some mock data
private getUser(name: string): Observable<{name: string, age: number}> {
return timer(2000).pipe(map(() => {
return {name, age: Math.round(Math.random() * 30 + 10)};
}));
}
}
<input type="text" class="form-control" [(ngModel)]="text"
[myFocus]="isFocused" [disabled]="isDisabled"
(keydown)="podcastsKeyDown($event)">
<p>{{account | json}}</p>
推荐阅读
- ubuntu - Bitbucket 管道:bash:cap:找不到命令
- c# - MEF 未列出插件
- python - 使用 pandas、python 为数据框创建辅助轴
- python - 如何修复moviepy中to_soundarray的越界错误?
- jquery - 在受信任的 Angular 注入的 HTML 中注册 jQuery 事件
- typescript - 通过对象递归检查未定义的值
- java - 使用 rtc plain java api 生成完整的流操作历史报告
- javascript - ./src/App.jsx 中的错误未找到模块:错误:无法解析“./component/Footer”
- javascript - 使用 AngularJS 将复杂对象发布到 MVC 控制器
- azure-cosmosdb - 无法在 2 个 cosmos 容器之间迁移