在同一页面上多次引导Angular应用程序

在同一页面上多次引导Angular应用程序,angular,Angular,我想在同一页上多次引导Angular 4 micro应用程序。基本上,对于类“.angular micro app”的每个实例,引导一个新的应用实例 我知道传统上,这些都是单亲应用程序中的角度组件。在我的情况下,这是不可能的,我需要同一个根级别应用程序(组件)的多个实例,在同一个页面上。对于AngularJS 1.x来说,这相当微不足道,但对于AngularJS 1.x来说,这是相当令人沮丧的 例如: index.html代码段: <body> <div class=“.ang

我想在同一页上多次引导Angular 4 micro应用程序。基本上,对于类“.angular micro app”的每个实例,引导一个新的应用实例

我知道传统上,这些都是单亲应用程序中的角度组件。在我的情况下,这是不可能的,我需要同一个根级别应用程序(组件)的多个实例,在同一个页面上。对于AngularJS 1.x来说,这相当微不足道,但对于AngularJS 1.x来说,这是相当令人沮丧的

例如:

index.html代码段:

<body>
<div class=“.angular-micro-app”></div>
…
<div class=“.angular-micro-app”></div> <!-- this element is NOT bootstrapping -->
</body>
app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
  ],
  providers: [

  ],
  bootstrap: [AppComponent],
})
export class AppModule { }
在主文件中,我正在执行基本平台引导:

platformBrowserDynamic().bootstrapModule(AppModule);

这可以通过在NgModule ngDoBootstrap方法中手动引导根级组件来实现

(注意,在角度5+中,可能不再需要此方法,请参阅)

我们首先找到要引导的所有根元素,并给它们一个唯一的ID。然后对于每个实例,用新ID攻击组件工厂选择器并触发引导

const entryComponents = [
  RootComponent,
];

@NgModule({
  entryComponents,
  imports: [
    BrowserModule,
  ],
  declarations: [
    RootComponent,
  ],
})
export class MyModule {
  constructor(private resolver: ComponentFactoryResolver) {}

  ngDoBootstrap(appRef: ApplicationRef) {
    entryComponents.forEach((component: any) => {
      const factory = this.resolver.resolveComponentFactory(component);
      let selectorName;
      let elements;

      // if selector is a class
      if (factory.selector.startsWith('.')) {
        selectorName = factory.selector.replace(/^\./, '');
        elements = document.getElementsByClassName(selectorName);

      // else assume selector is an element
      } else {
        selectorName = factory.selector;
        elements = document.getElementsByTagName(selectorName);
      }

      // no elements found, early return
      if (elements.length === 0) {
        return;
      }

      // more than one root level componenet found, bootstrap unique instances
      if (elements.length > 1) {
        const originalSelector = factory.selector;

        for (let i = 0; i < elements.length; i += 1) {
          elements[i].id = selectorName + '_' + i;
          (<any>factory).factory.selector = '#' + elements[i].id;
          appRef.bootstrap(factory);
        }

        (<any>factory).factory.selector = originalSelector;

      // only a single root level component found, bootstrap as usual
      } else {
        appRef.bootstrap(factory);
      }
    });
  }
}
const entryComponents=[
根组件,
];
@NGD模块({
入口组件,
进口:[
浏览器模块,
],
声明:[
根组件,
],
})
导出类MyModule{
构造函数(专用冲突解决程序:ComponentFactoryResolver){}
ngDoBootstrap(appRef:ApplicationRef){
entryComponents.forEach((组件:any)=>{
const factory=this.resolver.resolveComponentFactory(组件);
让我们选择名称;
让元素;
//如果选择器是一个类
if(factory.selector.startsWith('.')){
selectorName=factory.selector.replace(/^\./,“”);
elements=document.getElementsByClassName(selectorName);
//否则,假定选择器是一个元素
}否则{
selectorName=factory.selector;
elements=document.getElementsByTagName(selectorName);
}
//未找到元素,请提前返回
if(elements.length==0){
返回;
}
//找到多个根级组件集,引导唯一实例
如果(元素长度>1){
const originalSelector=factory.selector;
for(设i=0;i
现在,假设我们的RootComponent的选择器为“.angular micro app”,这将按预期工作:

<body>
    <div class="angular-micro-app"></div>
    ...
    <div class="angular-micro-app"></div>
</body>

...
<body>
    <div class="angular-micro-app"></div>
    ...
    <div class="angular-micro-app"></div>
</body>