Tom
Tom

Reputation: 4151

Multiple instances of the same root application in Angular 2

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

Upvotes: 5

Views: 2303

Answers (2)

Tom
Tom

Reputation: 4151

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.

Upvotes: 2

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657118

That's currently not supported. There is an open issue to allow to override the selector when bootstrap() is called.

https://github.com/angular/angular/issues/7136

Upvotes: 1

Related Questions