首页 文章

同一页上的Bootstrap Angular App多次

提问于
浏览
3

我想在同一页面上多次引导一个Angular 4微应用程序 . 基本上,foreach类的实例'.angular-micro-app',引导一个新的app实例 .

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

例:

index.html代码段:

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

app.component.ts:

import { Component } from '@angular/core';

@Component({
  selector: '.angular-micro-app',
  template: require('./app.component.html'),
})
export class AppComponent { }

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);

1 回答

  • 0

    这可以通过在NgModule ngDoBootstrap方法中手动引导根级别组件来完成 .

    (注意,在Angular 5中,可能不再需要此方法,请参阅this Angular PR

    我们首先找到我们想要引导的所有根元素,并为它们提供唯一的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);
          }
        });
      }
    }
    

    现在,假设我们的RootComponent的选择器是'.angular-micro-app',这将按预期工作:

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

相关问题