renderer2 nativeelement manipulate example elementref angular

nativeelement - Cómo obtener el elemento dom en angular 2



nativeelement angular 4 (3)

Use ViewChild con #localvariable como se muestra aquí,

<textarea #someVar id="tasknote" name="tasknote" [(ngModel)]="taskNote" placeholder="{{ notePlaceholder }}" style="background-color: pink" (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} </textarea>

En componente,

Manera más antigua

import {ElementRef} from ''@angular/core''; @ViewChild(''someVar'') el:ElementRef; ngAfterViewInit() { this.el.nativeElement.focus(); }

Vieja forma

import {ElementRef} from ''@angular/core''; @ViewChild(''someVar'') el:ElementRef; constructor(private rd: Renderer) {} ngAfterViewInit() { this.rd.invokeElementMethod(this.el.nativeElement,''focus''); }

Actualizado el 22/03 (marzo) / 2017

Nueva manera

Tenga en cuenta que desde Angular v4.0.0-rc.3 (2017-03-10) se han cambiado algunas cosas. Dado que el equipo de Angular despreciará invokeElementMethod , el código anterior ya no se puede usar.

ROMPIENDO CAMBIOS

desde 4.0 rc.1:

renombrar RendererV2 a Renderer2
renombrar RendererTypeV2 a RendererType2
renombrar RendererFactoryV2 a RendererFactory2

import {ElementRef,Renderer2} from ''@angular/core''; @ViewChild(''someVar'') el:ElementRef; constructor(private rd: Renderer2) {} ngAfterViewInit() { console.log(this.rd); this.el.nativeElement.focus(); //<<<=====same as oldest way }

console.log(this.rd) le dará los siguientes métodos y puede ver que invokeElementMethod no está allí. Adjuntar img todavía no está documentado.

NOTA: Puede utilizar los siguientes métodos de Rendere2 con / sin la variable ViewChild para hacer tantas cosas.

Esta pregunta ya tiene una respuesta aquí:

Tengo un componente que tiene un elemento p . Su evento onClick lo cambiará a un área de textarea para que el usuario pueda editar los datos. Mi pregunta es:

  • ¿Cómo puedo enfocarme en el área de texto?
  • ¿Cómo puedo alcanzar el elemento para poder aplicar el .focus () en él?
  • ¿Puedo evitar usar document.getElemenntById ()?

Intenté usar el "ElementRef" y el "@ViewChild ()", pero parece que me falta algo:

// ------ THE CLASS @ViewChild(''tasknoteId'') taskNoteRef:ElementRef; noteEditMode: boolean = false; get isShowNote (){ return !this.noteEditMode && this.todo.note ? true : false; } taskNote: string; toggleNoteEditMode () { this.noteEditMode = !this.noteEditMode; this.renderer.invokeElementMethod(this.taskNoteRef.nativeElement,''focus''); } // ------ THE COMPONENT <span class="the-insert"> <form [hidden]="!noteEditMode && todo.note"> <textarea #tasknoteId id="tasknote" name="tasknote" [(ngModel)]="todo.note" placeholder="{{ notePlaceholder }}" style="background-color:pink" (blur)="updateNote()" (click)="toggleNoteEditMode()" [autofocus]="noteEditMode" [innerHTML]="todo.note"> </textarea> </form> </span>


Actualización (usando el procesador):

Tenga en cuenta que el servicio Renderer original ahora ha quedado en desuso a favor de Renderer2

como en el documento oficial de Renderer2.

Además, como señaló @ GünterZöchbauer:

En realidad, usar ElementRef está bien. También está bien usar ElementRef.nativeElement con Renderer2. Lo que se desaconseja es acceder a las propiedades de ElementRef.nativeElement.xxx directamente.

Puede lograr esto utilizando elementRef y ViewChild . sin embargo, no es recomendable usar elementRef debido a:

  • problema de seguridad
  • acoplamiento apretado

como lo señala la documentación oficial de ng2 .

1. Usando elementRef (acceso directo):

export class MyComponent { constructor (private _elementRef : elementRef) { this._elementRef.nativeElement.querySelector(''textarea'').focus(); } }

2. Usando ViewChild ( mejor enfoque ):

<textarea #tasknote name="tasknote" [(ngModel)]="taskNote" placeholder="{{ notePlaceholder }}" style="background-color: pink" (blur)="updateNote() ; noteEditMode = false " (click)="noteEditMode = false"> {{ todo.note }} </textarea> // <-- changes id to local var export class MyComponent implements AfterViewInit { @ViewChild(''tasknote'') input: ElementRef; ngAfterViewInit() { this.input.nativeElement.focus(); } }

3. Usando el renderer :

export class MyComponent implements AfterViewInit { @ViewChild(''tasknote'') input: ElementRef; constructor(private renderer: Renderer2){ } ngAfterViewInit() { //using selectRootElement instead of depreaced invokeElementMethod this.renderer.selectRootElement(this.input["nativeElement"]).focus(); } }


Angular 2.0.0 Final:

Descubrí que usar un setter ViewChild es la forma más confiable de establecer el foco de control de formulario inicial:

@ViewChild("myInput") set myInput(_input: ElementRef | undefined) { if (_input !== undefined) { setTimeout(() => { this._renderer.invokeElementMethod(_input.nativeElement, "focus"); }, 0); } }

Primero se llama al setter con un valor undefined seguido de una llamada con un ElementRef inicializado.

Ejemplo de trabajo y fuente completa aquí: http://plnkr.co/edit/u0sLLi?p=preview

Uso de TypeScript 2.0.3 Final / RTM, Angular 2.0.0 Final / RTM y Chrome 53.0.2785.116 m (64 bits).

ACTUALIZACIÓN para Angular 4+

Renderer ha quedado en desuso a favor de Renderer2 , pero Renderer2 no tiene el invokeElementMethod . Deberá acceder al DOM directamente para establecer el foco como en input.nativeElement.focus() .

Todavía encuentro que el enfoque de establecimiento de ViewChild funciona mejor. Cuando uso AfterViewInit , a veces obtengo la read property ''nativeElement'' of undefined error read property ''nativeElement'' of undefined .

@ViewChild("myInput") set myInput(_input: ElementRef | undefined) { if (_input !== undefined) { setTimeout(() => { //This setTimeout call may not be necessary anymore. _input.nativeElement.focus(); }, 0); } }