简体   繁体   English

如何在 Angular 6 中手动设置 mat-form-field 的焦点

[英]How to manually set focus on mat-form-field in Angular 6

I am new to angular ,In my application I have a mat-dialog in which I have two forms namely Login and SignUp.我是 angular 的新手,在我的应用程序中,我有一个 mat-dialog,其中有两个表单,即登录和注册。

Once I open the dialog first time the auto focus is set on username field.problem is when I navigate to SignUp form on button click that form's FIrst Name field not get auto focused ,the same way navigate from signup to login the username field is now not get auto focused.一旦我第一次打开对话框,自动焦点设置在用户名字段上。问题是当我导航到注册表单按钮单击该表单的第一个名称字段不会自动聚焦时,从注册到登录用户名字段的导航方式相同不会自动对焦。

I have tried to some stackoverflow solutions but nothing is resolved my issue.我尝试了一些 stackoverflow 解决方案,但没有解决我的问题。

popupScreen.component.html popupScreen.component.html

<form class="login" *ngIf="isLoginHide">
    <mat-form-field>
        <input matInput placeholder="username">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="password">
    </mat-form-field>

    <button mat-button color="primary">Login</button>
    <button mat-button (click)="hideLogin($event)" color="accent">SignUp</button>
</form>

<form class="SignUp" *ngIf="isSignUpHide">
    <mat-form-field>
        <input matInput placeholder="First Name">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="Last Name">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="username">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="password">
    </mat-form-field>

    <button mat-button (click)="hideSignUp($event)" color="primary">Login</button>
    <button mat-button color="accent">SignUp</button>
</form>

can anyone help me to solve this .谁能帮我解决这个问题。

Kindly use cdkFocusInitial attribute in input field where you want to focus.请在要聚焦的输入字段中使用cdkFocusInitial属性。

<mat-form-field>
    <input matInput placeholder="username" #usernameInput cdkFocusInitial>
</mat-form-field>

Almost .. :-), If you are using some Materials component like MatSelect - above solutions does not work.几乎.. :-),如果您使用的是诸如 MatSelect 之类的材料组件 - 上述解决方案不起作用。 Below you can find a solution that work for me.您可以在下面找到适合我的解决方案。

<mat-form-field>
    <mat-select #myElement ......>
       ..........
    </mat-select>
<mat-form-field>

then in component...然后在组件中...

@ViewChild('myElement') firstItem: MatSelect;

ngAfterViewInit() {
   this.firstItem.focus();
   this.cd.detectChanges();
}

bear in mind that you have to force change detection after setting focus to avoid Angular error : " ExpressionChangedAfterItHasBeenCheckedError " (btw you have to include also " ChangeDetectorRef " in your component constructor)请记住,您必须在设置焦点后强制更改检测以避免 Angular 错误:“ ExpressionChangedAfterItHasBeenCheckedError ”(顺便说一句,您还必须在组件构造函数中包含“ ChangeDetectorRef ”)

Hope this help ...希望这有助于...

This works for me in Angular 8:这在 Angular 8 中对我有用:

<mat-form-field>
    <input matInput placeholder="First Name" #firstname>
</mat-form-field>

.ts .ts

export class TestComponent implements OnInit {

    @ViewChild('firstname', {static: true}) firstname:any;

    ngOnInit() {
      this.firstname.nativeElement.focus();
    }

}

Have you tried adding autofocus to the form field for First name ?您是否尝试将autofocus添加到First name的表单字段中?

<form class="SignUp" *ngIf="isSignUpHide">
    <mat-form-field>
        <input matInput placeholder="First Name" autofocus>
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="Last Name">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="username">
    </mat-form-field>
    <mat-form-field>
        <input matInput placeholder="password">
    </mat-form-field>

    <button mat-button (click)="hideSignUp($event)" color="primary">Login</button>
    <button mat-button color="accent">SignUp</button>
</form>

You can use MatInput for set autofocus您可以使用MatInput设置自动对焦

here's is an example,这是一个例子,

in component.htmlcomponent.html

<mat-form-field>
    <input matInput placeholder="First Name" #firstname="matInput">
</mat-form-field>

and in component.ts并在component.ts

import { MatInput } from '@angular/material/input';

export class Component implements OnInit {

    @ViewChild('firstname') nameInput: MatInput;

    ngOnInit() {
       this.nameInput.focus();
    }
}

use can use native element's focus. use 可以使用原生元素的焦点。

havn't tested this code, but something like this:没有测试过这段代码,但类似这样:

<mat-form-field>
    <input matInput placeholder="username" #usernameInput>
</mat-form-field>

on your component:在您的组件上:

@ViewChild('usernameInput') usrFld: ElementRef;

ngAfterViewInit() {
  this.usrFld.nativeElement.focus();
}

ps: you should be routing to a signup component rather than using ngIf for navigation. ps:您应该路由到注册组件而不是使用ngIf进行导航。

This works for me:这对我有用:

<mat-label >Radio name:</mat-label>
   <input type="text" #inputName="matInput" matInput formControlName="name" placeholder="Type radio name"/>
</mat-form-field>

  @ViewChild('inputName', { static: false }) inputName: MatInput;

  ngAfterViewInit(): void {
    setTimeout(() => this.inputName.focus(), 0);
  }

setTimeout is rather a hack to avoid change detection issue. setTimeout是一种避免变更检测问题的技巧。 I don't know why, but executing change detecion manually doesn't work in my case.我不知道为什么,但手动执行更改检测在我的情况下不起作用。

For MatDialog you will have to delay the action with setTimeout对于MatDialog,您将不得不使用setTimeout延迟操作

<mat-form-field>
  <mat-label>Name</mat-label>
  <input #inputName="matInput" matInput formControlName="name">
</mat-form-field>

@ViewChild('inputName') inputName: MatInput;

ngAfterViewInit() {
  setTimeout(() => {
    this.inputName.focus();
  });
}

Be aware that depending on when and how your component is displayed, ngOnInit may not be the place to set the focus.请注意,根据组件的显示时间和方式,ngOnInit 可能不是设置焦点的地方。

For example, if ComponentOne's html looks like this:例如,如果 ComponentOne 的 html 如下所示:

  <ng-container *ngIf='something === true'>
    <app-component-two></app-component-two>
  </ng-container>

And ComponentTwo has your input element and ComponentTwo's ts file is set up correctly, then putting this in your component-two.component.ts file:并且 ComponentTwo 具有您的输入元素并且 ComponentTwo 的 ts 文件设置正确,然后将其放入您的 component-two.component.ts 文件中:

ngOnInit() {
  this.myInput.focus();
}

May not work because the html for ComponentTwo has not been rendered yet, meaning that even with the ViewChild correct, this.myInput has not been rendered and is null.可能无法工作,因为 ComponentTwo 的 html 尚未呈现,这意味着即使 ViewChild 正确, this.myInput 也未呈现并且为空。

ngAfterViewInit() {
  this.myInput.focus();
}

Even if you are not nesting components, you may still need to pay attention to the lifecycle of the html to make sure that your focus command occurs after the input element has been rendered.即使您没有嵌套组件,您可能仍然需要注意 html 的生命周期,以确保您的焦点命令在输入元素呈现后发生。

Check out https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence for more information about the angular lifecycle.查看https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence了解有关 angular 生命周期的更多信息。

Such a simple and ordinary thing to do but most of above didn't work for me.如此简单而普通的事情要做,但上面的大部分内容对我都不起作用。

The cdkFocusInitial works great unless you are using a stepper control or equivalent where you want a new input to be focussed on stepper.next(). cdkFocusInitial 工作得很好,除非您使用步进器控件或等效项,您希望新输入集中在 stepper.next() 上。

I ended up NOT using viewchild to get a reference to the object, and instead good old fashioned ids.我最终没有使用 viewchild 来获取对对象的引用,而是使用了老式的 id。

public setFocus(input: string) {
   const targetElem = document.getElementById(input);
   setTimeout(function waitTargetElem() {
    if (document.body.contains(targetElem)) {
      targetElem.focus();
    } else {
      setTimeout(waitTargetElem, 100);
    }
  }, 500);
}

call it with...用...调用它

this.setfocus('id of your input')

The solution for this is very simple, Use Angular Material CDK option cdkFocusInitial解决这个问题的方法很简单,使用 Angular Material CDK 选项cdkFocusInitial

<mat-form-field>
    <input matInput placeholder="username" cdkFocusInitial>
</mat-form-field>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM