我有一个预先存在的,成熟的,非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>
接下来,如果我在AppComponent中的任何地方调用platformBrowserDynamic().bootstrapModule(AppModule);
并设置value = '111'
,我的HTML看起来像:
<body>
<my-app>
<span>111</span>
</my-app>
</body>
然后我在HTML中添加了另一个my-app
选择器,如下所示:
<body>
<my-app>
<span>111</span>
</my-app>
<my-app>
</my-app>
</body>
然后,如果我在AppComponent逻辑中的任何地方调用platformBrowserDynamic().bootstrapModule(AppModule);
并在新创建的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个可见实例?
谢谢!
答案 0 :(得分: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