Angular 2在组件加载时将焦点放在表单的第一个字段上
Posted
技术标签:
【中文标题】Angular 2在组件加载时将焦点放在表单的第一个字段上【英文标题】:Angular 2 Set focus on first field of form on component load 【发布时间】:2017-01-27 17:17:38 【问题描述】:在我的应用程序中,我想在组件加载时自动将焦点设置在表单的第一个字段上。任何人都可以指导如何在不重复的情况下实现这一点,因为我希望在我的应用程序中的每个表单(反应式表单)上都这样做。
【问题讨论】:
【参考方案1】:您应该使用指令来实现此行为。
这将向您展示如何做到这一点:https://plnkr.co/edit/ttxCP7vCLkLtNb3Xiaah?p=preview
import Component, NgModule, Directive, ElementRef, Renderer from '@angular/core'
import BrowserModule from '@angular/platform-browser'
@Directive(
selector: 'form[anyNameHere]'
)
export class SelectFirstInputDirective
constructor(private _eRef: ElementRef, private _renderer : Renderer)
private _getInputElement(nativeElement: any): any
if (!nativeElement || !nativeElement.children) return undefined;
if (!nativeElement.children.length && nativeElement.localName === 'input' && !nativeElement.hidden) return nativeElement;
let input;
[].slice.call(nativeElement.children).every(c =>
input = this._getInputElement(c);
if (input) return false; // break
return true; // continue!
);
return input;
ngAfterViewInit()
let formChildren = [].slice.call(this._eRef.nativeElement.children);
formChildren.every(child =>
let input = this._getInputElement(child);
if (input)
this._renderer.invokeElementMethod(input, 'focus', []);
return false; // break!
return true; // continue!
);
@Component(
selector: 'my-app',
template: `
<div>
<h2>Hello name</h2>
<form anyNameHere>
<div class="form-group">
<input hidden formcontrolname="firstName" type="text" class="form-control input-sm ng-pristine ng-valid ng-touched" placeholder="First Name" id="firstName">
<label class="col-sm-3 control-label" for="firstName">Name</label>
<div class="col-sm-9 form-inline">
<div class="form-group">
<div class="col-sm-12">
<input formcontrolname="firstName" type="text" class="form-control input-sm ng-pristine ng-valid ng-touched" placeholder="First Name" id="firstName">
</div>
</div>
<div class="form-group">
<div class="col-sm-12">
<input formcontrolname="lastName" type="text" class="form-control input-sm ng-untouched ng-pristine ng-valid" placeholder="Last Name" id="lastName">
</div>
</div>
</div>
</div>
</form>
</div>
`,
)
export class App
constructor()
this.name = 'Angular2'
@NgModule(
imports: [ BrowserModule ],
declarations: [ App, SelectFirstInputDirective ],
bootstrap: [ App ]
)
export class AppModule
【讨论】:
非常感谢@mxii。显然,上述指令应将焦点设置在表单中的第一个输入字段上,并在 plunker 中完成。但是当我在我的应用程序中测试它时它不起作用,可能是因为在我的情况下输入字段位于 div 标签下。有没有办法只查询和选择输入元素,然后将焦点设置为第一个输入。目前您正在使用 this._eRef.nativeElement.children 选择表单的所有子级。 查看我更新的答案/plunker..您需要进行递归搜索! :) 非常感谢@mxii,但它有时有效,有时无效。请看plnkr.co/edit/vvdq8IMsGjDAAM2YiO1P?p=preview 绝对有效,但哇,只是为了设置输入焦点! @mxii 它在页面重新加载时有效,但不重新加载就无法工作,我做错了什么?【参考方案2】:在 Angular 4 中,Renderer 已被弃用,因此指令方式已不复存在。但无论如何,您始终可以使用“快速而肮脏”的方式:将引用添加到您要设置焦点的元素,然后使用 <reference-name>.focus()
<form [formGroup]="form" (ngSubmit)="onSubmit(form, $event); needFocus.focus()">
<input placeholder="" formControlName="name" #needFocus>
</form>
【讨论】:
【参考方案3】:您可以使用以下方法 => 1. 您可以通过 autoFoucs 指令或 2. 提供对您的控件的引用,例如
<input hidden #firstName formcontrolname="firstName" type="text" class="form-control input-sm ng-pristine ng-valid ng-touched" placeholder="First Name" id="firstName">
然后在ts文件中这样声明
export class App implements OnInit
@ViewChild('firstName') firstNameTextbox;
constructor()
ngOnInit()
this.firstNameTextbox.nativeElement.focus();
【讨论】:
【参考方案4】:您可以通过简单地将“autofocus”属性添加到您的输入元素来实现这一点。
<input class="form-control" [formControl]="name" autofocus>
【讨论】:
页面加载完成后输入才会获得焦点。但是,如果您在应用程序中导航并返回页面,则输入将不再获得焦点。自动对焦不太适合单页应用。 您可以在视图 中为您的输入创建一个引用,然后您可以在组件类 @ViewChild('myname') 输入中访问它; ngAfterViewInit() this.input.focus; 这仅在您对输入进行硬编码而不是使用 ngFor 动态生成时才有用【参考方案5】:html autofocus attribute 正是这样做的
<input type="text" name="fname" autofocus>
【讨论】:
【参考方案6】:import AfterViewInit, Directive, ElementRef from '@angular/core';
@Directive(
selector: 'form[appFocusFirstInput]'
)
export class FocusFirstInputDirective implements AfterViewInit
constructor(
private element: ElementRef
)
ngAfterViewInit(): void
const input = this.element.nativeElement.querySelector('input');
if (input)
input.focus();
【讨论】:
以上是关于Angular 2在组件加载时将焦点放在表单的第一个字段上的主要内容,如果未能解决你的问题,请参考以下文章
第一次加载时未从 url 查询参数初始化 Angular 7 变量