En lugar de inyectar ElementRef
y usar querySelector
o similar desde allí, se puede usar una forma declarativa para acceder directamente a los elementos en la vista:
<input #myname>
@ViewChild('myname') input;
elemento
ngAfterViewInit() {
console.log(this.input.nativeElement.value);
}
Ejemplo de StackBlitz
- @ViewChild () admite el tipo de directiva o componente como parámetro, o el nombre (cadena) de una variable de plantilla.
- @ViewChildren () también admite una lista de nombres como lista separada por comas (actualmente no se permiten espacios
@ViewChildren('var1,var2,var3')
).
- @ContentChild () y @ContentChildren () hacen lo mismo pero a la luz DOM (
<ng-content>
elementos proyectados).
descendientes
@ContentChildren()
es el único que permite consultar también descendientes
@ContentChildren(SomeTypeOrVarName, {descendants: true}) someField;
{descendants: true}
debería ser el valor predeterminado pero no está en la versión 2.0.0 final y se considera un error
Esto se solucionó en 2.0.1
leer
Si hay un componente y directivas, el read
parámetro permite especificar qué instancia debe devolverse.
Por ejemplo, ViewContainerRef
eso es requerido por los componentes creados dinámicamente en lugar del predeterminadoElementRef
@ViewChild('myname', { read: ViewContainerRef }) target;
suscribir cambios
Aunque los elementos secundarios de vista solo se configuran cuando ngAfterViewInit()
se llama y los elementos secundarios de contenido solo se configuran cuando ngAfterContentInit()
se llama, si desea suscribirse a los cambios del resultado de la consulta, debe hacerlo enngOnInit()
https://github.com/angular/angular/issues/9689#issuecomment-229247134
@ViewChildren(SomeType) viewChildren;
@ContentChildren(SomeType) contentChildren;
ngOnInit() {
this.viewChildren.changes.subscribe(changes => console.log(changes));
this.contentChildren.changes.subscribe(changes => console.log(changes));
}
acceso DOM directo
solo puede consultar elementos DOM, pero no componentes o instancias de directivas:
export class MyComponent {
constructor(private elRef:ElementRef) {}
ngAfterViewInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
// for transcluded content
ngAfterContentInit() {
var div = this.elRef.nativeElement.querySelector('div');
console.log(div);
}
}
obtener contenido proyectado arbitrario
Ver Acceso a contenido transcluido
input
también es unElementRef
, pero obtienes la referencia al elemento que realmente deseas, en lugar de consultarlo desde el hostElementRef
.ElementRef
está bien. También usarElementRef.nativeElement
conRenderer
está bien. Lo que se desaconseja es acceder a las propiedades deElementRef.nativeElement.xxx
directamente.ElementRef.nativeElement)
decir, no le permite usar angulares representación del lado del servidor y función WebWorker (no sé si también se rompe la próxima plantilla compilador en línea - pero supongo que no).@ViewChild('myObj', { read: ElementRef }) myObj: ElementRef;
Puede obtener un identificador para el elemento DOM mediante la
ElementRef
inyección en el constructor de su componente:Documentos: https://angular.io/docs/ts/latest/api/core/index/ElementRef-class.html
fuente
ElementRef
se ha ido.ElementRef
está disponible (¿otra vez?)this.element.nativeElement.querySelector('#someElementId')
y pasar ElementRef al constructor así ...private element: ElementRef,
Importar lib ...import { ElementRef } from '@angular/core';
Ejemplo actualizado para trabajar con la última versión
Para más detalles sobre el elemento nativo, aquí
fuente
Angular 4+ : se usa
renderer.selectRootElement
con un selector CSS para acceder al elemento.Tengo un formulario que inicialmente muestra una entrada de correo electrónico. Después de ingresar el correo electrónico, el formulario se ampliará para permitirles continuar agregando información relacionada con su proyecto. Sin embargo, si son no un cliente existente, el formulario incluye una sección de dirección por encima de la sección de información del proyecto.
A partir de ahora, la parte de entrada de datos no se ha dividido en componentes, por lo que las secciones se administran con directivas * ngIf. Necesito poner el foco en el campo de notas del proyecto si son clientes existentes, o en el campo de nombre si son nuevos.
Probé las soluciones sin éxito. Sin embargo, la Actualización 3 en esta respuesta me dio la mitad de la solución final. La otra mitad provino de la respuesta de MatteoNY en este hilo. El resultado es este:
Como lo único que estoy haciendo es enfocarme en un elemento, no necesito preocuparme por la detección de cambios, por lo que puedo ejecutar la llamada desde
renderer.selectRootElement
fuera de Angular. Debido a que necesito dar tiempo a las nuevas secciones para que se procesen, la sección del elemento se ajusta en un tiempo de espera para permitir que los hilos de representación se pongan al día antes de que se intente la selección del elemento. Una vez que todo está configurado, simplemente puedo llamar al elemento usando selectores básicos de CSS.Sé que este ejemplo se ocupó principalmente del evento de enfoque, pero es difícil para mí que esto no pueda usarse en otros contextos.
fuente
Para las personas que intentan tomar la instancia del componente dentro de un
*ngIf
o*ngSwitchCase
, puedes seguir este truco.Crea una
init
directiva.Exporte su componente con un nombre como
myComponent
Use esta plantilla para obtener la instancia
ElementRef
ANDMyComponent
Use este código en TypeScript
fuente
importar el
ViewChild
decorador desde@angular/core
, así:Código HTML:
Código TS:
ahora puede usar el objeto 'myForm' para acceder a cualquier elemento dentro de él en la clase.
Source
fuente
fuente
inputTxt
en ese caso.Nota : Esto no se aplica a Angular 6 y superior como se
ElementRef
hizoElementRef<T>
alT
denotar el tipo denativeElement
.Me gustaría agregar que si está utilizando
ElementRef
, como lo recomiendan todas las respuestas, inmediatamente se encontrará con el problema queElementRef
tiene una declaración de tipo horrible que se pareceEsto es estúpido en un entorno de navegador donde nativeElement es un
HTMLElement
.Para solucionar esto, puede usar la siguiente técnica
fuente
item
tiene que ser un RefElement, a pesar de que se está configurando a otro RefElement:let item:ElementRef, item2:ElementRef; item = item2; // no can do.
. Muy confuso. Pero esto está bien:let item:ElementRef, item2:ElementRef; item = item2.nativeElement
debido a la implementación que señaló.let item: ElementRef, item2: ElementRef; item = item2
falla debido al análisis de asignación definitiva. Su segundo falla por los mismos motivos, pero ambos tienen éxito siitem2
se inicializa por los motivos discutidos (o como una comprobación rápida útil de asignabilidad que podemos usardeclare let
aquí). De todos modos, es realmente una pena verany
en una API pública como esta.para obtener el próximo hermano inmediato, use esto
fuente
Selección del elemento objetivo de la lista. Es fácil seleccionar un elemento particular de la lista de los mismos elementos.
código de componente:
código HTML:
código css:
fuente
Ejemplo mínimo para un uso rápido:
#inputEl
de la<input>
etiqueta.ngAfterViewInit
gancho del ciclo de vida.Nota:
Si desea manipular los elementos DOM, use la API Renderer2 en lugar de acceder a los elementos directamente. Permitir el acceso directo al DOM puede hacer que su aplicación sea más vulnerable a los ataques XSS
fuente