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);
}
}