2

I'm making migration from asp.net web forms to Angular 4. I'm making it step by step. Replacing one part and placing it in production. I face a problem with loading same Angular app several times in page. For example with code

<root tag="table-ep-component" data="5800"></root>
<root tag="table-ep-component" data="3333"></root>

there is only one loaded app in the page - the first one. How can I make them work both? Any suggestions are welcome

IAfanasov
  • 4,775
  • 3
  • 27
  • 42
  • Why do you need the same app multiple times, rather than the same component multiple times within one app? – jonrsharpe Aug 26 '17 at 14:22
  • Main page markup is generated by asp.net web forms so far and we are not close to full migration to Angular4. Asp.net web forms tells that this component should be in this place. Some components are Angular4 apps. And sometimes it should be several Angular4 components in one pages in different places. Haven't found other real life approach to migrate from web forms to Angular step by step and can not migrate in one step - too much work for one step. – IAfanasov Aug 26 '17 at 14:34
  • You can render app one time on first demand and put needed component inside. When this part is not needed you hide tag and work with another parts of system. Next time you need angular form you show root container and put another form into it. What do you think? Just thoughts, I don't know how to do this :) – Sharikov Vladislav Aug 26 '17 at 15:25
  • Sometime I will need to show several Angular components in different places. Could imaging this working with some DOM manipulations. Like Load this component inside root and than move it to other place. Doesn't look like any reliable thing. still, thanks for idea (: – IAfanasov Aug 27 '17 at 08:36

1 Answers1

3

You can use Applicationref.bootstrap method to do it working:

abstract bootstrap<C>(
  componentFactory: ComponentFactory<C>|Type<C>,
  rootSelectorOrNode?: string|any): ComponentRef<C>;

As we can see this method can take rootSelectorOrNode parameter so we can bootstrap the same component twice.

ngDoBootstrap method on your root @NgModule can help us to manually bootstrap our application:

@NgModule({
   declarations: [AppComponent],
   imports: [BrowserModule], 
   entryComponents: [AppComponent]
})
export class MenuModule {
   ngDoBootstrap(appRef: ApplicationRef) {
     const rootElements = document.queryselectorAll('root');
     // cast due to https://github.com/Microsoft/TypeScript/issues/4947
     for (const element of rootElements as any as HTMLElement[]){
       appRef.bootstrap(AppComponent, element);
     }
   }
}

See also:

yurzui
  • 205,937
  • 32
  • 433
  • 399
  • it looks like what I need. Except for ngDoBootstrap don't called. Placed console.log where. I compile with Angular CLI in production mode with AoT. Investigating why doesn't it called. – IAfanasov Aug 27 '17 at 11:11
  • You should remove bootstrap property from NgModule metadata – yurzui Aug 27 '17 at 11:24
  • Why this approach shares all root services aross all apps? The same instance of services. How to set Angular to use separate services despite they are a root? –  Mar 19 '21 at 13:26