【问题标题】:Bootstrap Angular App Multiple Times on Same Page在同一页面上多次引导 Angular 应用程序
【发布时间】:2017-10-30 16:38:46
【问题描述】:

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

我了解传统上这些将是单个父应用程序中的 Angular 组件。就我而言,这是不可能的,我需要在同一页面上具有相同根级应用程序(组件)的多个实例。这对于 AngularJS 1.x 来说是相当微不足道的,但事实证明对于 Angular 来说相当令人沮丧。

例子:

index.html sn-p:

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

【问题讨论】:

    标签: angular


    【解决方案1】:

    这可以通过在 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-18
      • 2020-08-10
      • 2019-10-27
      • 2017-10-21
      • 1970-01-01
      • 2019-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多