Using Angular 2 Components in the Entire Angular Application

I have a fork of an existing, mature, non-w500> web application. I also have some existing Angular 2 components from a separate application that I want to reuse. I would like to sprinkle existing Angular components into an Angular app in different places. I would like to know if this is possible and advisable. Note that this is similar but not identical to spray Angular 2 component on a non-Angular page . I have a more specific scenario that I describe below.

I have currently figured out how to add separate instances of these Angular components by loading the module that wraps my desired component. For example. if i want to inject AppComponent into my existing Angular app:

In app.module.ts:

@NgModule({
  declarations: [AppComponent],
  bootstrap: [AppComponent]
})
export class AppModule { }

      

In app.component.ts:

@Component({
  selector: 'my-app'
  template: '<span>{{value}}</span>'
  ...
})
export class AppComponent { 
   public value: string;
   ...
 }

      

Whenever I want an AppComponent, I just add the element my-app

and load the module like this:

platformBrowserDynamic().bootstrapModule(AppModule);

      

This works great and gives the exact results I want for a single AppComponent instance. However, my use cases require that I have two concurrent AppComponent instances in different places in the DOM. If I try to load the AppModule a second time, then the main Angular code attaches the second AppModule to the element my-app

that appears first in the DOM, effectively erasing my first AppModule instance. Is there a way to tell Angular which element to my-app

add to? Or is there some way to get around this?

Example HTML :

Let's say add <my-app>

to <body>

. Then my HTML looks like this:

<body>
  <my-app>
  </my-app>
</body>

      

Then if I call platformBrowserDynamic().bootstrapModule(AppModule);

and set value = '111'

anywhere on the AppComponent, my HTML looks like this:

<body>
  <my-app>
    <span>111</span>
  </my-app>
</body>

      

Then I add another selector to the HTML my-app

, so it looks like this:

<body>
  <my-app>
    <span>111</span>
  </my-app>
  <my-app>
  </my-app>
</body>

      

Then if I call platformBrowserDynamic().bootstrapModule(AppModule);

and set value = '222'

in the newly created AppComponenet anywhere in the AppComponent logic, my HTML looks like this:

<body>
  <my-app>
    <span>222</span>
  </my-app>
  <my-app>
  </my-app>
</body>

      

when i need the desired result:

<body>
  <my-app>
    <span>111</span>
  </my-app>
  <my-app>
    <span>222</span>
  </my-app>
</body>

      

In short: Is it possible and advisable to use Angular components throughout an Angular application? Is it possible to have 2 visible instances of the same Angular module at the same time?

Thank!

+3


source to share


1 answer


Following your scenario, I will write the following code:

let bootstrapComponentFn: (node: HTMLElement) => void;

platformBrowserDynamic().bootstrapModule(AppModule).then((moduleRef: 

  NgModuleRef<AppModule) => {
    const appRef = moduleRef.injector.get(ApplicationRef);
    const zone: NgZone = moduleRef.injector.get(NgZone);
    const rootComponentFactory = (moduleRef as any).bootstrapFactories[0];  

    bootstrapComponentFn = (node) => {
      zone.run(() => {
        const compRef = rootComponentFactory.create(Injector.NULL, [], node);
       appRef.attachView(compRef.hostView);
      })
    }; 
  });
}

      

Some time later



setTimeout(function() {
  let node = document.createElement('my-app');
  document.body.appendChild(node);

  bootstrapComponentFn(node);
}, 2000);

      

See also Plunger example

+2


source







All Articles