发布于 4年前

Angular在启动页index.html多次重复使用组件的方法

默认情况下,在angular的index.html只能使用一个根标签作为应用的入口,如:

<!DOCTYPE html>
<html>
 <head>
  <base href="." />
 </head> 
 <body>
   <app-root></app-root>
 </body>
</html>

如果要在index.html页面多次使用组件,可以在模块的ngDoBootstrap()方法里添加:

app.ts

根组件app.ts定义组件,组件选择器为"my-app"

import { Component, NgModule, Inject, OpaqueToken } from '@angular/core'
import { BrowserModule } from '@angular/platform-browser'

import { ApplicationRef, ComponentFactory, ComponentFactoryResolver, Type } from '@angular/core';

@Component({
 selector: 'my-app',
 template: `
  <div>
   <h2>Hello {{name}}</h2>
  </div>
 `,
})
export class App {
 name:string;
 constructor() {
  this.name = 'Angular'
 }
}

export const BOOTSTRAP_COMPONENTS_TOKEN = new OpaqueToken('bootstrap_components');

@NgModule({
 imports: [ BrowserModule ],
 declarations: [ App ],
 entryComponents: [ App ]
})
export class AppModule {
  constructor(
    private resolver : ComponentFactoryResolver
    @Inject(BOOTSTRAP_COMPONENTS_TOKEN) private components
  ) {}

  ngDoBootstrap(appRef : ApplicationRef) {
    this.components.forEach((componentDef : {type: Type<any>, selector: string}) => {
     const factory = this.resolver.resolveComponentFactory(componentDef.type);
     factory.selector = componentDef.selector;
     appRef.bootstrap(factory);
    });
  }
}

在AppModule的构造函数里注入在index.html使用的组件components,它在main.ts里声明注册。

核心代码在ngDoBootstrap():

ngDoBootstrap(appRef : ApplicationRef) {
    this.components.forEach((componentDef : {type: Type<any>, selector: string}) => {
     const factory = this.resolver.resolveComponentFactory(componentDef.type);
     factory.selector = componentDef.selector;
     appRef.bootstrap(factory);
    });
  }

main.ts

angular 应用入口

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {AppModule, App, BOOTSTRAP_COMPONENTS_TOKEN} from './app';

const components = [
 { type: App, selector: "my-app#app-1" },
 { type: App, selector: "my-app#app-2" }
];

const platform = platformBrowserDynamic([
 {provide: BOOTSTRAP_COMPONENTS_TOKEN, useValue: components}
]);
platform.bootstrapModule(AppModule);

在入口的main.ts定义了在index.html跟页面使用的组件列表components,并且使用paltformBorwserDynamic()注册。

index.html

在index.html使用如下:

<!DOCTYPE html>
<html>

 <head>
  <base href="." />
  <title>angular2 playground</title>
  <link rel="stylesheet" href="style.css" />
  <script src="https://unpkg.com/zone.js/dist/zone.js"></script>
  <script src="https://unpkg.com/zone.js/dist/long-stack-trace-zone.js"></script>
  <script src="https://unpkg.com/reflect-metadata@0.1.3/Reflect.js"></script>
  <script src="https://unpkg.com/systemjs@0.19.31/dist/system.js"></script>
  <script src="config.js"></script>
  <script>
  System.import('app').catch(console.error.bind(console));
 </script>
 </head>

 <body>
  <my-app id="app-1">loading 1...</my-app>
  <my-app id="app-2">loading 2...</my-app>
 </body>

</html>

</body></html>

©2020 edoou.com   京ICP备16001874号-3