Как вручную установить фокус на поле mat-form-field в Angular 6

Я новичок в 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>

может ли кто-нибудь помочь мне решить эту проблему.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
26
0
53 998
10

Ответы 10

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>

да, впервые он работает, если я перемещаюсь между двумя формами с помощью нажатия кнопки без какого-либо взаимодействия с полями ввода, он не работает со второго раза, он не работает @Prashant

Zhu 03.09.2018 06:41

Это хорошо работает в форме с материалом Angular 10+, спасибо!

Elvynia 19.10.2020 20:18

Вы можете использовать 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

user12163165 18.07.2020 13:26

Не верю, что прошло почти два года, а решение проблемы еще не найдено

user12163165 18.07.2020 13:34

Пожалуйста, используйте атрибут cdkFocusInitial в поле ввода, на котором вы хотите сфокусироваться.

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

Это не работает. Если да, то предоставьте пример stackblitz.

Stefan 05.02.2019 10:11

Убедитесь, что cdkFocusInitial используется в форме только один раз. Поверь мне это работает.

kumardippu 06.02.2019 11:17

@kumardippu Trust me it works - Я бы не поверил себе, не увидев работающего примера ;-)

Mubin 09.03.2019 16:13

Размещение cdkFocusInitial на mat-slide-toggle сработало для меня

speckledcarp 24.09.2019 18:42

У меня сработало, когда я открыл MatDialog, основное внимание было уделено MatExpansionPanel, но я хотел, чтобы это было на кнопке. Установка cdkFocusInitial на кнопку сделала именно это.

dylanvdb 24.04.2020 15:32

Это не вопрос доверия. Это вопрос устранения неполадок. Рабочий пример может показать, чего не хватает оператору. Это может быть что-то столь же простое, как версия пакета, или разница в синтаксисе, или что-то еще мешающее.

Stoutie 05.05.2020 23:36

Вы очень вежливы, @kumardippu "Пожалуйста, используйте ....". Спасибо, у меня работает!

Lukuluba 28.05.2020 16:08

Почти .. :-), если вы используете какой-либо компонент материалов, например 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?

Igor 13.04.2020 16:05

cd - это "ChangeDetectorRef", упомянутый ранее.

jspassov 20.04.2020 17:05

Он войдет в конструктор как внедренная зависимость.

Brad Johnson 16.11.2020 22:32

Это работает для меня в 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 не нужен)

Russ 04.05.2020 22:12

Имейте в виду, что в зависимости от того, когда и как отображается ваш компонент, 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')

Другие вопросы по теме