Я новичок в angular. В моем приложении у меня есть диалоговое окно mat, в котором у меня есть две формы, а именно Login и SignUp.
Как только я открываю диалоговое окно в первый раз, когда автофокус устанавливается на поле имени пользователя. Проблема заключается в том, что я перехожу к форме SignUp при нажатии кнопки, поле FIrst Name этой формы не получает автофокусировку, точно так же переходите от регистрации до входа в поле имени пользователя. не получить автофокус.
Я пробовал использовать некоторые решения stackoverflow, но моя проблема не решена.
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>
может ли кто-нибудь помочь мне решить эту проблему.





use может использовать фокус родного элемента.
не тестировал этот код, но примерно так:
<mat-form-field>
<input matInput placeholder = "username" #usernameInput>
</mat-form-field>
на вашем компоненте:
@ViewChild('usernameInput') usrFld: ElementRef;
ngAfterViewInit() {
this.usrFld.nativeElement.focus();
}
p.s: вам следует выполнять маршрутизацию к компоненту регистрации, а не использовать ngIf для навигации.
Вы пробовали добавить 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>
Это хорошо работает в форме с материалом Angular 10+, спасибо!
Вы можете использовать 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();
}
}
this.nameInput - это undefined, когда вы используете его внутри ngOnInit, вам нужно вызвать его внутри ngAfterViewInit, но тогда вы получите ошибку, указанную @jspassov
Не верю, что прошло почти два года, а решение проблемы еще не найдено
Пожалуйста, используйте атрибут cdkFocusInitial в поле ввода, на котором вы хотите сфокусироваться.
<mat-form-field>
<input matInput placeholder = "username" #usernameInput cdkFocusInitial>
</mat-form-field>
Это не работает. Если да, то предоставьте пример stackblitz.
Убедитесь, что cdkFocusInitial используется в форме только один раз. Поверь мне это работает.
@kumardippu Trust me it works - Я бы не поверил себе, не увидев работающего примера ;-)
Размещение cdkFocusInitial на mat-slide-toggle сработало для меня
У меня сработало, когда я открыл MatDialog, основное внимание было уделено MatExpansionPanel, но я хотел, чтобы это было на кнопке. Установка cdkFocusInitial на кнопку сделала именно это.
Это не вопрос доверия. Это вопрос устранения неполадок. Рабочий пример может показать, чего не хватает оператору. Это может быть что-то столь же простое, как версия пакета, или разница в синтаксисе, или что-то еще мешающее.
Вы очень вежливы, @kumardippu "Пожалуйста, используйте ....". Спасибо, у меня работает!
Почти .. :-), если вы используете какой-либо компонент материалов, например 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» в свой конструктор компонента)
Надеюсь на эту помощь ...
Откуда в вашем примере переменная cd?
cd - это "ChangeDetectorRef", упомянутый ранее.
Он войдет в конструктор как внедренная зависимость.
Это работает для меня в Angular 8:
<mat-form-field>
<input matInput placeholder = "First Name" #firstname>
</mat-form-field>
.ts
export class TestComponent implements OnInit {
@ViewChild('firstname', {static: true}) firstname:any;
ngOnInit() {
this.firstname.nativeElement.focus();
}
}
Для меня это был правильный ответ (Angular 9, Материал 9). Для того, чтобы печатать стойкие, используйте ElementRef вместо any; (И static: true не нужен)
Имейте в виду, что в зависимости от того, когда и как отображается ваш компонент, ngOnInit может не подходить для установки фокуса.
Например, если HTML-код ComponentOne выглядит так:
<ng-container *ngIf='something === true'>
<app-component-two></app-component-two>
</ng-container>
И ComponentTwo имеет ваш входной элемент, и ts-файл ComponentTwo настроен правильно, а затем помещает его в свой файл component-two.component.ts:
ngOnInit() {
this.myInput.focus();
}
Может не работать, потому что html для ComponentTwo еще не отрисован, а это означает, что даже с правильным ViewChild this.myInput не был отрисован и имеет значение null.
ngAfterViewInit() {
this.myInput.focus();
}
Даже если вы не вкладываете компоненты, вам все равно может потребоваться обратить внимание на жизненный цикл html, чтобы убедиться, что ваша команда focus выполняется после того, как элемент ввода был отрисован.
Ознакомьтесь с https://angular.io/guide/lifecycle-hooks#lifecycle-event-sequence для получения дополнительной информации о жизненном цикле angular.
Для 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 - это скорее уловка, позволяющая избежать проблем с обнаружением изменений. Я не знаю почему, но выполнение обнаружения изменений вручную в моем случае не работает.
Такая простая и обыденная вещь, но большая часть вышеперечисленного у меня не сработала.
CdkFocusInitial отлично работает, если вы не используете шаговый элемент управления или его эквивалент, если вы хотите, чтобы новый ввод был сфокусирован на stepper.next ().
В итоге я НЕ использовал viewchild для получения ссылки на объект, а вместо этого использовал старые добрые идентификаторы.
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')
да, впервые он работает, если я перемещаюсь между двумя формами с помощью нажатия кнопки без какого-либо взаимодействия с полями ввода, он не работает со второго раза, он не работает @Prashant