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 已被弃用,因此指令方式已不复存在。但无论如何,您始终可以使用“快速而肮脏”的方式:将引用添加到您要设置焦点的元素,然后使用 &lt;reference-name&gt;.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 正是这样做的

&lt;input type="text" name="fname" autofocus&gt;

【讨论】:

【参考方案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 变量

如何在表单加载中对文本框设置焦点

Angular 2 表单验证器弄乱了取消按钮

Angular2 - 将文本框集中在组件加载上

TailwindCSS 在 Angular(延迟加载)子组件中不起作用

在页面加载时将焦点设置在 HTML 输入框上