我有一个预先存在的,成熟的,非Angular Web应用程序的分支.我还有一些我希望重用的独立应用程序中现有的Angular 2组件.我想将现有的Angular组件分散到各个地方的非Angular应用程序中.我想知道这是否可行和可行.请注意,这与 Sprinkling Angular 2 components inside a non-angular page
相似但不完全相同.我有一个更具体的场景,我将在下面介绍.
目前,我已经想出如何通过引导包装我所需组件的模块来添加这些Angular组件的单个实例.例如.如果我想将AppComponent插入到我现有的非Angular应用程序中:
在app.module.ts中:
@NgModule({
declarations: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
在app.component.ts中:
@Component({
selector: 'my-app'
template: '<span>{{value}}</span>'
...
})
export class AppComponent {
public value: string;
...
}
每当我想要一个AppComponent时,我只需附加一个my-app元素并按如下方式引导模块:
platformBrowserDynamic().bootstrapModule(AppModule);
这完全正常,并为AppComponent的单个实例提供了我想要的精确结果.但是,我的用例要求我在DOM的不同位置同时有两个AppComponent实例.如果我第二次尝试引导AppModule,核心Angular代码会将第二个AppModule附加到DOM中首先出现的my-app元素,从而有效地删除我的第一个AppModule实例.有没有办法告诉Angular要追加哪个my-app元素?或者有什么方法可以解决这个问题?
HTML示例:
假设我追加一个< my-app>到< body>.然后我的HTML看起来像:
<body>
<my-app>
</my-app>
</body>
接下来,如果我调用platformBrowserDynamic().bootstrapModule(AppModule);并在AppComponent中的任何位置设置value =’111′,我的HTML看起来像:
<body>
<my-app>
<span>111</span>
</my-app>
</body>
然后我将另一个my-app选择器添加到HTML中,所以它看起来像:
<body>
<my-app>
<span>111</span>
</my-app>
<my-app>
</my-app>
</body>
然后,如果我调用platformBrowserDynamic().bootstrapModule(AppModule);并在AppComponent逻辑中的任何地方新设置的AppComponenet中设置value =’222′,我的HTML如下所示:
<body>
<my-app>
<span>222</span>
</my-app>
<my-app>
</my-app>
</body>
当我想要的结果是:
<body>
<my-app>
<span>111</span>
</my-app>
<my-app>
<span>222</span>
</my-app>
</body>
总结:在非Angular应用程序中使用Angular组件是否可行且可取?是否可以同时拥有同一个角度模块的2个可见实例?
谢谢!
最佳答案 根据您的方案,我将编写以下代码:
let bootstrapComponentFn: (node: HTMLElement) => void;
platformBrowserDynamic().bootstrapModule(AppModule).then((moduleRef:
NgModuleRef<AppModule) => {
const appRef = moduleRef.injector.get(ApplicationRef);
const zone: NgZone = moduleRef.injector.get(NgZone);
const rootComponentFactory = (moduleRef as any).bootstrapFactories[0];
bootstrapComponentFn = (node) => {
zone.run(() => {
const compRef = rootComponentFactory.create(Injector.NULL, [], node);
appRef.attachView(compRef.hostView);
})
};
});
}
一段时间以后
setTimeout(function() {
let node = document.createElement('my-app');
document.body.appendChild(node);
bootstrapComponentFn(node);
}, 2000);
另见Plunker Example