Автофокус, который работает в любое время в приложениях Angular

Kate

Administrator
Команда форума
Я вижу, что многие разработчики борются со следующим сценарием; они хотят, чтобы фокусируемый элемент, такой как ввод, получил фокус, когда он изначально виден.
Первое, что все пытаются сделать, - это добавить к элементу собственный атрибут автофокуса:

<input autofocus>
view rawmy22.component.html hosted with ❤ by GitHub

Затем страница обновляется, и вуаля - все работает. Элемент сфокусирован. Однако есть два важных случая, когда этот метод может не работать. Первый случай - это когда вы достигнете этого элемента без перезагрузки страницы, например он появляется после навигации в одностраничном приложении. Второй - когда элемент отображается условно, например, с помощью директивы ngIf.
Тот факт, что он не работает, не имеет ничего общего с Angular. Если мы посмотрим на спецификацию, мы найдем следующее объяснение:
Атрибут содержимого autofocus позволяет автору указать, что элемент управления должен быть сфокусирован, как только страница загружается или как только отображается диалоговое окно, в котором он находится, что позволяет пользователю просто начать вводить без необходимости вручную фокусировать основной контроль.

Как мы можем узнать из спецификации, элемент будет сфокусирован только один раз - при загрузке страницы. В двух вышеупомянутых случаях страница уже загружена, поэтому работать не будет.
Чтобы реализовать эту функциональность, мы создадим директиву, которая плавно добавит ее к нашим элементам:


import { Directive, ElementRef } from '@angular/core';

@Directive({
selector: '[autofocus]'
})
export class AutofocusDirective {
constructor(private host: ElementRef) {}

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

autofocus.directive.ts hosted with ❤ by GitHub view raw


Мы нацелены на каждый элемент с помощью атрибута autofocus и явно вызываем метод focus () в его хуке ngAfterViewInit. Мы также можем сделать еще один шаг и предоставить ввод, который будет фокусировать элемент на основе его значения.

Интересный факт - чтобы получить ту же функциональность в React, вы можете использовать свойство authFocus, которое делает то же самое.

Наконец, у меня есть еще один совет по работе с директивой ngIf и изменению элемента в зависимости от его видимости:

@Component({
selector: 'app-root',
template: `
<button (click)="show = !show">Toggle</button>
<input *ngIf="show" #input>

})
export class AppComponent {
@ViewChild('input', { static: false })
set input(element: ElementRef<HTMLInputElement>) {
if(element) {
element.nativeElement.focus()
}
}
}

setter-ex.comp.ts hosted with ❤ by GitHub view raw


Мы можем использовать запрос ViewChild вместе с сеттером. Angular будет вызывать сеттер каждый раз, когда элемент добавляется или удаляется из представления.
Если мы запрашиваем несколько элементов с помощью ViewChildren, мы можем использовать наблюдаемые изменения для наблюдения за видимостью элементов.


Если вы это пропустили
Вот несколько моих проектов с открытым исходным кодом:
Akita государственное управление, специально разработанное для приложений JS
Spectator: мощный инструмент для упрощения ваших угловых тестов
Transloco: библиотека интернационализации Angular
error-tailer - Бесшовные формы ошибок для приложений Angular
Forms Manager: основа правильного управления формами в Angular
Cashew: гибкая и простая библиотека, которая кэширует HTTP-запросы.
Error Tailor - Бесшовные формы ошибок для приложений Angular
И многое другое!

Перевод статьи с сайта: https://netbasal.com/
 
Сверху