Búsqueda de sitios web

javascript - Angular 2 - comunicación de funciones de TypeScript con bibliotecas externas de js


Usando Javascript Infovis Toolkit como una biblioteca externa para dibujar gráficos y árboles. Necesito manipular el método onClick de los nodos para enviar de manera asíncrona una solicitud HTTP GET al servidor y asignar los datos que provienen del servidor a las propiedades y variables de una clase de servicio de Angular. Al usar webpack para empaquetar todos los tipos de archivos TypeScript compilados en un solo archivo js, el archivo de salida es confuso e ilegible. Así que llamar a una función que está en el archivo js compilado desde una biblioteca js externa, claramente no es la mejor solución.

Intento la siguiente solución dentro de mi servicio Angular para poder acceder a las propiedades de este servicio sin ningún problema:

document.addEventListener('DOMContentLoaded', function () {
  
  var nodes = document.querySelectorAll(".nodes"); // nodes = []
  
  for (var i = 0; i < nodes.length; i++) { // nodes.length = 0
    
    nodes[i].addEventListener("click", function () {
      
      // asynchronously sending GET request to the server
      // and assing receiving data to the properties of this Angular service
      
    });
  }

});

Sin embargo, esta solución no funciona porque en Javascript Infovis Toolkit los nodos se dibujan después de terminar de renderizar el DOM y también después del evento window.onload. Esta biblioteca tiene algunos métodos del ciclo de vida como onAfterCompute() que se llama después de que se completa el dibujo del árbol. ¿Cómo puedo activar un evento global para informar al servicio de Angular que el dibujo del árbol se ha completado y que puede consultar todos los nodos?

Respuesta #1

Simplemente dispara un evento personalizado usando dispatchEvent.

En Angular puedes escuchar añadiendo a cualquier componente que realmente esté agregado al DOM:

  • en cualquier plantilla:
<div (window:custom-event)="updateNodes($event)">
  • o en la clase de componentes:
@HostListener('window:custom-event', ['$event']) 
updateNodes(event) {
  ...
}
  • o en la anotación @Component() o @Directive():
@Component({
  selector: '...',
  host: {'(window:custom-event)':'updateNodes($event)'}
})

donde custom-event es el tipo del evento despachado y updateNodes(event) es un método en la clase de tu componente.

Para activarlo manualmente en JavaScript:

window.dispatchEvent(new Event('custom-event'));

Un enfoque alternativo

sería hacer que los métodos de los componentes (o directivas, servicios) estén disponibles fuera de Angular como se explica en Angular2: cómo llamar a la función de un componente desde fuera de la aplicación.

Artículos relacionados