Solución:
Para lograr lo que desea, deberá usar el Renderer (inyectándolo en el constructor con private renderer: Renderer
). El renderizador proporciona una abstracción sobre los elementos nativos y proporciona una forma segura de interactuar con el DOM.
En su plantilla, debería poder hacer algo como esto:
<div (click)="menuToggle($event)"></div>
Esto captura el evento de clic y lo pasa al menuToggle
función.
Luego, en su componente, debería poder interactuar con el DOM usando el Renderer de esta manera:
menuToggle(event:any) {
this.renderer.setElementClass(event.target,"opened",true);
}
La firma de la función para setElementClass
, según los documentos es setElementClass(renderElement: any, className: string, isAdd: boolean) : void
Para leer más sobre Renderer, este es un buen artículo sobre Medium. Al hablar sobre el uso de ViewChild
y accediendo al DOM a través del nativeElement
en comparación con el uso de Renderer
, dice:
Esto funciona bien (usando nativeElement de ViewChild). Estamos tomando el elemento de entrada con la ayuda del decorador ViewChild y luego accedemos al elemento DOM nativo y llamamos al método focus () en la entrada.
El problema con este enfoque es que cuando accedemos al elemento nativo directamente, estamos renunciando a la abstracción DOM de Angular y perdemos la oportunidad de poder ejecutar también en entornos sin DOM como: móvil nativo, escritorio nativo, trabajador web. o renderizado del lado del servidor.
Recuerde que Angular es una plataforma, y el navegador es solo una de las opciones donde podemos renderizar nuestra aplicación.
Espero que esto ayude.
Desde la respuesta de Tyler, las cosas han cambiado un poco. Renderer
se deprecia y se reemplaza por Renderer2
. En Renderer 2
, la clase setElementClass
es reemplazado por addClass
. Y la nueva firma de funciones para addClass
, según los documentos es
addClass(el: any, name: string): void
Entonces el actualizado menuToggle
la función debería leer
menuToggle(event:any) {
this.renderer.addClass(event.target,"opened");
}