5

The system I am working on consists of a number of distributed microservices with potentially multiple versions of each component active at the same time.

The Angular2 app I am attempting to build shall be able to interact with each of these components by means of websockets. Because it seems unfeasible to prepare this application for all future versions and features of each component, the respective protocol implementation and even new components, I would like to push this responsibility to the components itself.

Each component is able to communicate its capabilities (in the form of a NG2 component) as well as the protocol implementation and the necessary GUI elements (HTML/CSS) via a package sent over the very same websocket connection.

Is there a pattern that enables this kind of 'on-demand-loading' of components and their templates in ng2?

Jens Habegger
  • 5,266
  • 41
  • 57
  • Can each component live on it's own on the top-level of the page (body), each as an independent Angular applications side by side which just communicate with each other or do they need to be nested like actual components. – Günter Zöchbauer Apr 22 '16 at 11:34
  • There is no need for the components to be nested or to interact with each other, but they should be able to share services and libraries. – Jens Habegger Apr 22 '16 at 11:36
  • 1
    Something like http://stackoverflow.com/questions/36566698/cant-initialize-dynamically-appended-component-in-angular-2/36566919?noredirect=1#comment60736661_36566919 would then work I guess. I don't know about how to do this with applications that are loaded at different times. For example how to make one application find a class of another after minification when names are mangled. – Günter Zöchbauer Apr 22 '16 at 11:39
  • That looks promising, thank you, I'll attempt to replicate it. – Jens Habegger Apr 22 '16 at 11:43

3 Answers3

2

It looks like you can try to use router lazy loading and provide custom implementation of NgModuleFactoryLoader which can load components via websocket.

kemsky
  • 14,727
  • 3
  • 32
  • 51
  • Could you elaborate on that? – Jens Habegger Feb 22 '17 at 06:40
  • Lazy loading feature modules is built-in functionality of the router, loading can be customized by providing implementation of `NgModuleFactoryLoader`. So if want to load modules using web sockets then you have to provide custom loader. – kemsky Feb 22 '17 at 12:55
  • NgModuleFactoryLoader expects a load(path:string) method to be implemented. Do you suggest: receive a string of a compiled feature_module.js via websocket, save it to a temporary file, feed the temporary files path into a custom NgModuleFactoryLoader implementation ? – Jens Habegger Feb 22 '17 at 15:42
  • Path is used to create arguments for module loader (systemjs, webpack etc.) which will automatically load pre-compiled feature module. Check systemjs implemetation https://github.com/angular/angular/blob/8f5dd1f11e6ca1888fdbd3231c06d6df00aba5cc/modules/%40angular/core/src/linker/system_js_ng_module_factory_loader.ts – kemsky Feb 22 '17 at 16:13
1

I am not quite sure if I fully understand your question.

Is there a pattern that enables this kind of 'on-demand-loading' of components and their templates in ng2?

Well there is on-demand-loading of modules, using lazy loaded modules, see: https://angular.io/docs/ts/latest/guide/ngmodule.html#!#lazy-load I highly recommend reading this whole guide, it is really helpful.

but they should be able to share services and libraries.

Angulars guide suggests a shared module and a core module for that. Actually I think that is really the best way to do it. Just scroll down on the link above.

Each component is able to communicate its capabilities (in the form of a NG2 component) as well as the protocol implementation and the necessary GUI elements (HTML/CSS) via a package sent over the very same websocket connection.

This is the part that I am unsure about, like I don't know if I understand correctly what you mean. You don't want to load a component through a websocket connection right? If so, then why? If you mean only communication for every component with the same websocket: I'd recommend a service doing that, which would be part of the Core Module and hence be a Singleton. The components can then access this service and therefore they are always connected to the same websocket.

bergben
  • 1,385
  • 1
  • 16
  • 35
  • 1
    Thank you for your answer. I've implemented a prototype based on the answers by bergben and kemsky. Unfortunately, I cannot split the bounty evenly across both posts. A coin flip decided to give the bounty to bergben. – Jens Habegger Feb 28 '17 at 06:58
0

Below is the steps can be achieved.

  • use systemjs loader to load components in your router ``
  • in your systemjs config file provide the path of the component

these examples explans more in detail.

Aniruddha Das
  • 20,520
  • 23
  • 96
  • 132