dom - manipular - Angular 2 @ViewChild devuelve indefinido
viewchild angular 5 español (4)
A veces, si el componente aún no se ha inicializado cuando se accede a él, aparece un error que indica que el componente hijo no está definido.
Sin embargo, incluso si accede al componente secundario en AfterViewInit, a veces el @ViewChild seguía devolviendo el valor nulo. El problema puede ser causado por la directiva * ngIf u otra.
La solución es usar @ViewChildren en lugar de @ViewChild y suscribir los cambios de suscripción que se ejecutan cuando el componente está listo.
Por ejemplo, si en el componente principal ParentComponent desea acceder al componente secundario MyComponent.
import { Component, ViewChildren, AfterViewInit, QueryList } from ''@angular/core'';
import { MyComponent } from ''./mycomponent.component'';
export class ParentComponent implements AfterViewInit
{
//other code emitted for clarity
@ViewChildren(MyComponent) childrenComponent: QueryList<MyComponent>;
public ngAfterViewInit(): void
{
this.childrenComponent.changes.subscribe((comps: QueryList<MyComponent>) =>
{
// Now you can access the child component
});
}
}
He examinado varias publicaciones y documentación relacionadas, pero aún parece que no puedo obtener el comportamiento esperado de @ViewChild.
En última instancia, estoy tratando de establecer la posición de desplazamiento de un div. Este elemento no es un componente, sino un div normal en mi HTML.
Para lograr esto, estoy tratando de usar @ViewChild para obtener el elemento DOM que necesito y establecer su valor de desplazamiento. (Aparte de eso, si conoce una mejor forma de lograr esto sin @ViewChild (o jQuery), las respuestas serán muy apreciadas).
Por el momento, @ViewChild solo devuelve indefinido. Pasando por algunos controles ficticios: - Estoy accediendo a mi elemento en AfterViewInit - No tengo ninguna otra directiva como * ngIf o * ngFor en este elemento.
Aquí está el controlador:
import { Component, AfterViewInit, ViewChild, ElementRef } from ''@angular/core'';
@Component({
selector: ''portfolio-page'',
templateUrl: ''./portfolio-page.component.html'',
styleUrls: [''./portfolio-page.component.scss'']
})
export class PortfolioPageComponent implements AfterViewInit{
@ViewChild(''gallery-container'') galleryContainer: ElementRef;
ngAfterViewInit(){
console.log(''My element: '' + this.galleryContainer);
}
}
Y la plantilla:
<div id=''gallery-container'' class=''gallery-image-container''>
<div class=''gallery-padding''></div>
<img class=''gallery-image'' src=''{{ coverPhotoVm }}'' />
<img class=''gallery-image'' src=''{{ imagepath }}'' *ngFor=''let imagepath of imagesVm'' />
</div>
Mi salida es simple: Mi elemento: indefinido.
Como puede ver, actualmente estoy intentando acceder al elemento por ID, pero también he intentado el nombre de clase. ¿Podría alguien proporcionar más detalles sobre lo que espera la consulta del selector ViewChild?
También he visto ejemplos en los que se utiliza un hash ''#'' como identificador del selector que utiliza @ViewChild - - pero esto provoca un error de análisis de la plantilla para mí con # gallery-container.
No puedo pensar en otra cosa que pueda estar equivocada aquí. Toda la ayuda es apreciada, gracias!
Código completo disponible aquí: https://github.com/aconfee/KimbyArting/tree/master/client/KimbyArting/components/portfolio-page
Suscribiéndose a cambios en
@ViewChildren(MyComponent) childrenComponent: QueryList<MyComponent>
funcionamiento confirmado, combinado con setTimeout()
y notifyOnChanges()
y comprobación cuidadosa de null
.
Cualquier otro enfoque produce resultados no confiables y es difícil de probar.
Trate de usar un ref en su plantilla en su lugar:
<div id=''gallery-container'' #galleryContainer class=''gallery-image-container''>
<div class=''gallery-padding''></div>
<img class=''gallery-image'' src=''{{ coverPhotoVm }}'' />
<img class=''gallery-image'' src=''{{ imagepath }}'' *ngFor=''let imagepath of imagesVm'' />
</div>
Y usa el nombre de referencia como argumento:
@ViewChild(''galleryContainer'') galleryContainer: ElementRef;
EDITAR
Olvidé mencionar que cualquier vista de niño así declarada solo está disponible después de que la vista se haya inicializado. La primera vez que esto sucede es en ngAfterViewInit
(importar e implementar la interfaz AfterViewInit
).
El nombre de referencia no debe contener guiones o esto no funcionará
Tuve un problema similar A diferencia de usted, mi @ViewChild
devolvió un ElementRef
válido, pero cuando intenté acceder a su elemento nativeElement
, no estaba undefined
.
Lo resolví configurando el id
vista como #content
, no como #content = "ngModel"
.
<textarea type = "text"
id = "content"
name = "content"
#content
[(ngModel)] = "article.content"
required></textarea>