How to focus on the field?

I upgraded from Angular 2 to Angular 4 and the docs say use Renderer2 instead of Renderer which is deprecated.

Right now I'm looking at the source of the Renderer, but cannot find a way to call the focus() method as before.

Old method:

this.renderer.invokeElementMethod(element, 'focus', []);

What is the new approach?

EDIT

What if the element I'm focusing on is QuerySelector through a QuerySelector ?

For instance:

 let inputField = document.querySelectorAll('.dialog input'); if ( inputField[0] ) { inputField[0].focus(); } 

Since it is obtained through QuerySelector , the focus() method does not exist.

+11
source share
6 answers

invokeElementMethod deprecated and will not return to a new renderer. To set focus on an element, you can simply use this now:

 element.nativeElement.focus(); 

If you use document.querySelectorAll , you are doing something not angular, and you should find another way to do this. If there is no other way to do this, then the same principle applies. The focus() method is simple javascript, so you can use it in angular2 / typescript. Be sure to make querySelectorAll inside the hook of the ngAfterViewInit component:

 ngAfterViewInit() { let inputField: HTMLElement = <HTMLElement>document.querySelectorAll('.dialog input')[0]; inputField && inputField.focus(); } 
+18
source

You can also use the selectRootElement Renderer2 method.

For instance:

 constructor(private renderer: Renderer2) {} this.renderer.selectRootElement('#domElementId').focus() 

where domElementId id = 'domElementId' in your html

+13
source
 template reference variable :#inlineEditControl <input #inlineEditControl class="form-control form-control-lg" [placeholder]="label"> @ViewChild('inlineEditControl') inlineEditControl: ElementRef; // input DOM element this.inlineEditControl.nativeElement.focus(); 
+5
source

Currently, it seems that this task is not achievable without directly modifying the DOM. As others have said, invokeElementMethod () is deprecated. However, you will find problems using selectRootElement, as this is not its target, and you will lose children inside your DIV. Here is a link to a SO question that explains selectRootElement in more detail (since angular docs are awful):

Renderer multiple selectRootElement Issue (with plnkr provided)

At the moment, it seems that the only way to easily achieve your goal is to use a template reference variable, a child of the view, and your viewChild.nativeElement.focus () (although this practice is also not recommended)

There is also a workaround using FocusService found in this GitHub issue: https://github.com/angular/angular/issues/15674

In this release, Tytskyi mentions that you can implement FocusService and provide various focus () implementations based on AppModuleBrowser and AppModuleServer. I'm not sure about the details of how this works, but this may be the only way to achieve this without using nativeElement at this time.

+1
source

If you declare the correct type of your inputField var, you can use any JS query selector.

For cases announcing:
let inputField: HTMLInputElement = document.querySelector('.dialog input');
allows you to call
inputField.focus();
that this will work, and no TS error will be thrown.

0
source

If you use the Angular CDK , you can set the focus using the FocusMonitor.focusVia method, which is part of the @angular/cdk/a11y module (A11yModule).

Thus, you can avoid any manipulations with the DOM and not refer to nativeElement at nativeElement .

 import { FocusMonitor } from '@angular/cdk/a11y'; export class ExampleComponent implements AfterViewInit { @ViewChild('elem', {static: false}) elemRef; constructor(private focusMonitor: FocusMonitor) { } ngAfterViewInit() { // Programmatically set focus. Focus source is 'program'. this.focusMonitor.focusVia(this.elemRef, 'program'); } } 
0
source

Source: https://habr.com/ru/post/1015992/


All Articles