默认情况下,在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>