关于typescript:如何在Angular 6中手动将焦点设置在mat-form-field上

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

我是angular的新手,在我的应用程序中,我有一个Mat-dialog,其中有两种形式,分别是Login和SignUp。

第一次打开对话框时,将自动焦点设置在用户名字段上。问题是当我单击按钮导航至"注册表单"时,表单的"名字"字段未自动聚焦,从注册到登录用户名字段现在不会自动聚焦。

我曾尝试过一些stackoverflow解决方案,但没有解决任何问题。

popupScreen.component.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<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>

谁能帮我解决这个问题。


几乎.. :-),如果您使用的是MatSelect之类的"材料"组件-上述解决方案将不起作用。您可以在下面找到适合我的解决方案。

1
2
3
4
5
<mat-form-field>
    <mat-select #myElement ......>
       ..........
    </mat-select>
<mat-form-field>

然后在组件中...

1
2
3
4
5
6
@ViewChild('myElement') firstItem: MatSelect;

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

请记住,您必须在设置焦点后强制更改检测以避免Angular错误:" ExpressionChangedAfterItHaHasBeenCheckedError"(顺便说一句,您还必须在组件构造函数中包括" ChangeDetectorRef")

希望获得帮助...


请在要聚焦的输入字段中使用cdkFocusInitial属性。

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


您可以使用MatInput设置自动对焦

这是一个例子,

component.html

中的

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

component.ts

1
2
3
4
5
6
7
8
9
10
import { MatInput } from '@angular/material/input';

export class Component implements OnInit {

    @ViewChild('firstname') nameInput: MatInput;

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


您是否尝试过将autofocus添加到名字的表单字段中?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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>


这在Angular 8中对我有效:

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

.ts

1
2
3
4
5
6
7
8
9
export class TestComponent implements OnInit {

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

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

}


use可以使用本机元素的焦点。

尚未测试此代码,但类似以下内容:

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

在您的组件上:

1
2
3
4
5
@ViewChild('usernameInput') usrFld: ElementRef;

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

p.s:您应该路由到注册组件,而不是使用ngIf进行导航。


这对我有用:

1
2
3
4
5
6
7
8
9
<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可以避免更改检测问题。我不知道为什么,但是在我的情况下,手动执行更改检测不起作用。


对于MatDialog,您必须使用setTimeout

延迟操作

1
2
3
4
5
6
7
8
9
10
11
12
<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();
  });
}

请注意,取决于显示组件的时间和方式,ngOnInit可能不是设置焦点的地方。

例如,如果ComponentOne的html如下所示:

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

然后ComponentTwo具有您的输入元素,并且正确设置了ComponentTwo的ts文件,然后将其放在您的component-two.component.ts文件中:

1
2
3
ngOnInit() {
  this.myInput.focus();
}

可能不起作用,因为尚未渲染ComponentTwo的html,这意味着即使正确使用了ViewChild,this.myInput也不会呈现并且为null。

1
2
3
ngAfterViewInit() {
  this.myInput.focus();
}

即使您不嵌套组件,也可能仍需要注意html的生命周期,以确保您的focus命令在呈现输入元素之后发生。

查看https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence以获得有关angular生命周期的更多信息。