Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - communication of typescript functions with external js libraries

Using Javascript Infovis Toolkit as an external library for drawing graph and trees. I need to manipulate the onClick method of nodes in order to asynchronously sending an HTTP GET request to the server and assign the data that comes from server to the properties and variables of an Angular service class. By Using webpack for packing all the compiled typescripts to a single js file, the output file is confusing and unreadable. so calling a function which is in the compiled js file from an external js library, is not the best solution clearly.

I try the following solution inside my Angular service so I can access to the properties of this service without any trouble:

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

});

However, this solution doesn't work because in Javascript Infovis Toolkit the nodes are drawn after finishing rendering of DOM and also after window.onload event. This library has some lifecycle methods such as onAfterCompute() which is called after drawing tree is completed. How can I trigger a global event to inform the Angular service that the drawing of tree is completed and it can query all of the nodes?

like image 557
rajabzz Avatar asked May 03 '16 06:05

rajabzz


1 Answers

Just fire a custom event using dispatchEvent.

In Angular you can listen by adding to any component that is actually added to the DOM:

  • in any template:
<div (window:custom-event)="updateNodes($event)">
  • or in the components class:
@HostListener('window:custom-event', ['$event']) 
updateNodes(event) {
  ...
}
  • or in the @Component() or @Directive() annotation:
@Component({
  selector: '...',
  host: {'(window:custom-event)':'updateNodes($event)'}
})

where custom-event is the type of the dispatched event and updateNodes(event) is a method in your components class.

To manually trigger it in JavaScript:

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

An alternative approach

would be to make methods of components (or directives, services) available outside Angular like explained in Angular2 - how to call component function from outside the app.

like image 80
Günter Zöchbauer Avatar answered Sep 19 '22 11:09

Günter Zöchbauer