Angular5:动态组件加载 – 具有@ angular/core依赖关系的Static
我正在将一个电子应用程序从AngularJS迁移到Angular5,我正面临着一个问题,我需要在其中加载任意模块及其组件,并将主要组件动态渲染到视图中(它是一个插件系统).
在我的应用程序中,插件是一个angular5模块,包含一个在angular5应用程序中渲染的组件. 我像这样动态加载组件: @ViewChild("view",{ read: ViewContainerRef }) view: ViewContainerRef; constructor( // ... private compiler: Compiler,private injector: Injector,private moduleRef: NgModuleRef<any> ) {} 然后, const addonModule = addonObject.getModule(); this.compiler .compileModuleAndAllComponentsAsync(addonModule) .then(factories => { const factory = factories.componentFactories.find( componentFactory => addonObject.getViewComponent().name == componentFactory.componentType.name ); if (factory) { const cmpRef = factory.create(this.injector,[],null,this.moduleRef); cmpRef.instance.config = { from: "afd@test.com",apikey: "dsfkjd" }; this.view.insert(cmpRef.hostView); } }); 它工作得很好但是当我在模板中添加Material Component时,它在factory.create()失败并出现此错误: 模板: <div> <button mat-button>test</button> </div> 错误: ERROR Error: Uncaught (in promise): Error: StaticInjectorError[Renderer2]: StaticInjectorError[Renderer2]: NullInjectorError: No provider for Renderer2! 要么 模板: <div fxLayout="row" fxFlex> test </div> 错误: ERROR Error: Uncaught (in promise): Error: StaticInjectorError[MediaMonitor]: StaticInjectorError[MediaMonitor]: NullInjectorError: No provider for MediaMonitor! Material模块似乎很好地导入了我的插件模块,如果它没有加载我有不同的行为:它忽略了指令(例如<按钮mat-button>< / button>只是一个< button>< / button>材料效果并且没有错误)和材料组件抛出错误(例如< mat-card> test< mat-card>抛出错误:模板解析错误:’mat-card’不是已知元素……) 我试图以多种不同的方式捆绑动态模块:tsc / ngc / ng-packagr / webpack. 当我在使用ng-cli构建的另一个应用程序的NgModule中正常导入(静态)时,该捆绑包正在工作. 有人知道如何动态渲染模板中使用了材料组件/指令的组件,如fxFlex / mat-button / mat-card? 编辑:我在这里用SystemJS复制了这个bug:https://github.com/thyb/repro-dynamic-loading Angular:5.0.2 角度材料:5.0.0-rc1
正如@yurzui在评论中解释的那样,@ angular / *依赖项被加载了两次.作为一种解决方法,我发现使其工作的唯一方法是使用窗口来共享应用程序和插件之间的@angular对象(@ angular / core,@ angular / common,@ angular / material).
在我的应用程序index.html中: window.angular = { core: require("@angular/core"),common: require("@angular/common"),material: require("@angular/material"),... } 在我的插件中: const NgModule = (window as any).angular.core.NgModule; const CommonModule = (window as any).angular.common.CommonModule; const MatButtonModule = (window as any).angular.material.MatButtonModule; ... 这不是很优雅(再见树摇晃),但至少它有效…如果有人有一个更简单的解决方案,我接受它:) 我遇到了关于Gitter约@angular/element的讨论,这似乎很有希望,因为它创建了独立/自包含的Web组件,可以动态注入而不会遇到我遇到的问题 – https://www.youtube.com/watch?v=ljsOPm4MMEo&feature=youtu.be&t=13m20s.这是一个实验室项目,因此在当前版本中不可用,但已经有了一些工作:https://github.com/angular/angular/pull/19469 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |