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



我是角度的新手,在我的应用程序中我有一个垫子对话框,其中我有两种形式,即登录和注册。

一旦我第一次打开对话框,自动焦点设置在用户名字段上.问题是当我导航到注册表单时,单击该表单的第一个名称字段没有自动聚焦,就像从注册导航到登录用户名字段现在没有自动聚焦一样。

我已经尝试了一些堆栈溢出解决方案,但没有任何解决我的问题。

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>

谁能帮我解决这个问题.

请在要关注的输入字段中使用cdkFocusInitial属性。

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

几乎.. :-(,如果您使用的是某些材质组件,例如MatSelect-上述解决方案不起作用。您可以在下面找到适合我的解决方案。

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

然后在组件中...

@ViewChild('myElement') firstItem: MatSelect;
ngAfterViewInit() {
this.firstItem.focus();
this.cd.detectChanges();
}

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

希望这个帮助...

这在 Angular 8 中对我有用:

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

.ts

export class TestComponent implements OnInit {
@ViewChild('firstname') firstname: ElementRef;
ngOnInit() {
this.firstname.nativeElement.focus();
}

}

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

<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>

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

这是一个例子,

component.html

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

并在component.ts

import { MatInput } from '@angular/material/input';
export class Component implements OnInit {
@ViewChild('firstname') nameInput: MatInput;
ngOnInit() {
this.nameInput.focus();
}
}

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

没有测试过这段代码,而是像这样:

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

在您的组件上:

@ViewChild('usernameInput') usrFld: ElementRef;
ngAfterViewInit() {
this.usrFld.nativeElement.focus();
}

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

对于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();
});
}

这对我有用:

<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是避免更改检测问题的黑客。我不知道为什么,但是手动执行更改检测在我的情况下不起作用。

解决方案非常简单,使用角度材料CDK选项cdkFocusInitial

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

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

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

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

ComponentTwo有你的输入元素,ComponentTwo 的 ts 文件设置正确,然后把它放在你的 component-two.component.ts 文件中:

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

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

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

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

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

这么简单而普通的事情要做,但上面的大部分都对我不起作用。

cdkFocusInitial工作得很好,除非您使用步进器控件或等效控件,您希望新输入集中在stepper.next((上。

我最终没有使用 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);
}

用...

this.setfocus('id of your input')

最新更新