Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple instances of the same root application in Angular 2

Tags:

angular

we integrate Angular 2 into a legacy page to make the functionality piece by piece more user friendly. So far exchanging prerendered backend widgets for angular modules has worked great.

However I ran into a problem that I don't know to solve: I have written a module/component that can occur multiple times on the page at different locations and with a different configuration.

  <body>
    <div class='somewhere-on-the-page'>
      <my-widget config='A'></my-widget>
    </div>
    <div class='somewhere-else-on-the-page'>
      <my-widget config='B'></my-widget>
    </div>
  </body>

Here is a Plunker of the case. You can see only the first occurrence is initialised. Is there any concept on how to tackle this? I think I cannot use a wrapper component since I cannot move the whole templating inside it (pages are rendered in the backend and angular directives are put in there).

Cheers

like image 960
Tom Avatar asked Oct 19 '22 02:10

Tom


1 Answers

Thanks to Tobias Bosch for some pointers he gave on github, this is a adjusted version of a workaround he proposed:

import {ApplicationRef_} from '<project-root>/node_modules/@angular/core/src/application_ref'

@NgModule({
  imports: [BrowserModule],
  declarations: [MyWidgetComponent],
  entryComponents: [MyWidgetComponent]
})
class MyWidgetModule {
  constructor(injector: Injector, cfr: ComponentFactoryResolver, appRef: ApplicationRef) {
    const widgetCompFactory = cfr.resolveComponentFactory(MyWidgetComponent);
    $(widgetCompFactory.selector).each((_, el) => {
        var compRef = widgetCompFactory.create(injector, [], el);
        var upcasted = <ApplicationRef_> appRef;
        upcasted.registerChangeDetector(compRef.changeDetectorRef);
    });
  }
}

Take care to import ApplicationRef_ from the angular file. You need to import it directly since it's not exported by default in the angular typings.

Alternatively you can use $('my-widget') (or any other selector you please) to get your DOM references, but I think it's cleaner to use the predefined selector on the component.

like image 140
Tom Avatar answered Nov 15 '22 05:11

Tom