我正在尝试开发我的WebApi(NETCORE(可插入应用程序的前端。我想使用Angular 9,但我不是Angular方面的专家。
我的后端被设计为可扩展的,在启动时,它会在指定的文件夹中进行监视,如果存在一个或多个dll文件,其中包含扩展基本应用程序的逻辑(如插件(,它会加载它们。我想在前端使用类似的方法。我尝试了不同的解决方案,阅读了很多文章,但很难找到想要在编译时导入未知插件的人。
我尝试了懒惰模块(从这个开始:https://www.mokkapps.de/blog/manually-lazy-load-modules-and-components-in-angular/)这将是完美的,但使用这个我必须在编译我的angular应用程序之前了解实现的插件(模块(,因为如果我想使用模块,我必须在我的主应用程序中使用Import函数。
因此,我搜索了更多内容,并在文章之后使用Angular CLI&Angular 5我尝试了System.Js的方法,但我找不到Angular 9的有效解决方案。
我很确定,我不是唯一一个会创建一个可插入的Angular应用程序的人,该应用程序加载插件而不重新编译主应用程序。
我需要一些建议来遵循正确的方法,或者一个使用插件架构的角度应用程序的工作示例。
我不确定这是一个更好、更优雅的解决方案,因为我是Angular的新手,但目前它对我很有效。
我假设插件是元素Web组件(https://angular.io/guide/elements)。为了创建我的第一个元素(插件(,我遵循了本教程:https://www.techiediaries.com/angular/angular-9-elements-web-components/.
顺便说一句,目前我无法正常加载插件,因为在编译项目以使用它之前,我必须知道我在元素中部署的组件的名称。我使用扩展元素找到了解决方案(https://angular-extensions.github.io/elements/#/home)。因此,我创建了一个动态组件,用于在运行时显示插件的组件。
这是动态组件的代码:
export class DynamicComponentContainerComponent implements OnInit {
plugin: Plugin
sub: any;
constructor(private route: ActivatedRoute, private pluginService: PluginService) { }
ngOnInit() {
this.sub = this.route
.data
.subscribe(data => {
this.pluginService.getPlugin(data['pluginName'])
.subscribe(
(res) => {
this.plugin = res;
},
(err) => {
console.error(err)
}
);
});
}
ngOnDestroy() {
this.sub.unsubscribe();
}
}
及其html模板:
<div *ngIf="plugin != null">
<ng-template #loading>Loading plugin {{plugin.tag}} ...</ng-template>
<ng-template #error>Error Loading plugin {{plugin.tag}}</ng-template>
<ax-lazy-element
*axLazyElementDynamic="plugin.tag; url: plugin.url; module: plugin.isModule;
errorTemplate: error; loadingTemplate: loading;">
</ax-lazy-element>
</div>
它可以工作,因为我的后端提供插件的JS编译文件(Element Web Component(,所以在使用它之前,我必须注册我的插件(因为我需要一些值来处理它,比如组件的名称或路由的路径(。事实上,动态组件中的axLazyElementDynamic属性需要JS元素Web组件文件的url和组件名称才能工作。
现在,我不得不为每个插件组件添加普通的路由路径。在我的应用程序组件中,我创建了一个简单的方法:
loadPlugins() {
this.pluginService.getPlugins()
.subscribe(plugins => {
plugins.forEach(plugin => {
this.router.config.unshift({ path: plugin.path, component:
DynamicComponentContainerComponent, data: { pluginName: plugin.name } });
this.links.push({ text: plugin.description, path: plugin.path });
});
});
}
插件服务只是从后端(我之前注册过插件的地方(获取插件数据。
我希望这能帮助到别人。