gpt4 book ai didi

Angular 5 : Dynamic component loading - StaticInjector error with @angular/core dependencies

转载 作者:太空狗 更新时间:2023-10-29 17:56:49 24 4
gpt4 key购买 nike

我正在将电子应用程序从 AngularJS 迁移到 Angular5,我在需要加载任意模块及其组件并将主要组件动态呈现到 View (它是一个插件系统)的部分中遇到问题。在我的应用程序中,插件是一个包含在我的 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 模块似乎很好地导入了我的插件模块,否则如果它没有加载我有不同的行为:它忽略指令(例如 <button mat-button></button> 只是一个 <button></button> 没有 Material 效果也没有错误)和 Material 组件抛出错误(例如 <mat-card>test<mat-card> 抛出 Error: Template parse errors: 'mat-card' is not a known element... )

我尝试以多种不同方式捆绑动态模块:tsc/ngc/ng-packagr/webpack。

当我在另一个使用 ng-cli 构建的应用程序的 NgModule 中正常(静态)导入它时,该包正在工作。

有人知道如何动态呈现具有模板中使用的 Material 组件/指令的组件,例如 fxFlex/mat-button/mat-card 吗?

编辑:我在这里用 SystemJS 复制了错误:https://github.com/thyb/repro-dynamic-loading

Angular :5.0.2

Angular Material :5.0.0-rc1

最佳答案

正如@yurzui 在评论中解释的那样,@angular/* 依赖项被加载了两次。作为一种解决方法,我发现使它工作的唯一方法是使用 window 在应用程序和插件之间共享 @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;
...

它不是很优雅(再见 tree shaking)但至少它有效...如果有人有更简单的解决方案,我会接受 :)

我在 Gitter 上看到了关于 @angular/element 的讨论这看起来很有前途,因为它创建了独立/自包含的 Web 组件,可以动态注入(inject)而没有我遇到的问题 - https://www.youtube.com/watch?v=ljsOPm4MMEo&feature=youtu.be&t=13m20s .这是一个实验室项目,因此在当前版本中不可用,但已经有一些工作:https://github.com/angular/angular/pull/19469

关于 Angular 5 : Dynamic component loading - StaticInjector error with @angular/core dependencies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47342589/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com