当前位置: 首页 > 知识库问答 >
问题:

Angular5:动态部件加载-静态喷油器错误,具有@angular/core相关性

祁渊
2023-03-14

我正在将一个electron应用程序从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);
    }
  });

它工作得很好,但是当我在模板中添加材质组件时,它在工厂失败了。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!

材料模块似乎很好地导入到我的插件模块中,否则如果没有加载,我会有不同的行为:它忽略指令(例如

我尝试过用许多不同的方式捆绑动态模块:tsc/ngc/ng-Packagr/webpack。

当我正常(静态)导入另一个用ng-cli构建的应用程序的Ng模块时,该捆绑包正在工作。

是否有人知道如何动态渲染模板中使用了材质组件/指令的组件,如fxFlex/mat按钮/mat卡?

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

角度:5.0。2.

角材质:5.0。0-rc1


共有1个答案

宇文良骏
2023-03-14

正如@yurzui在注释中解释的那样,@angular/*依赖项被加载了两次。作为一种解决方法,我发现使其工作的唯一方法是使用窗口在应用程序和插件之间共享@angular对象(@angular/core@angular/common@angular/material)。

在我的应用程序索引中。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上遇到了一个关于“角/元素”的讨论,这个讨论看起来很有希望,因为它创建了独立/独立的网络组件,可以动态注入,而不会遇到我遇到的问题——https://www.youtube.com/watch?v=ljsOPm4MMEo

 类似资料:
  • 你和你的朋友开车去提华纳度春假。你在为旅行存钱,所以你想把路上的油费降到最低。为了最小化你的汽油成本,你和你的朋友整理了以下信息。首先,你的汽车可以可靠地行驶m英里的油箱(但没有进一步)。你的一个朋友从网上挖掘了加油站的数据,并绘制了你路线上的每一个加油站,以及该加油站的汽油价格。具体而言,他们创建了一个从最近到最远的n+1个加油站价格列表,以及两个相邻加油站之间的n个距离列表。塔科马是0号加油站

  • 本文向大家介绍JS加载器如何动态加载外部js文件,包括了JS加载器如何动态加载外部js文件的使用技巧和注意事项,需要的朋友参考一下 今天在网上找到了一个可以动态加载js文件的js加载器,具体代码如下: JsLoader.js JsLoader.js测试 测试结果如下:

  • 问题内容: 我正在开发Web应用程序。我正在使用AngularJS将所有文件动态加载到UI中。 我有一个文件,可在单击或加载时将所有文件动态加载到其中。 现在我的登录页面看起来像下面的结构 现在我的问题是,尽管我能够加载手风琴的menu.html文件,但是却无法加载它所依赖的css和js文件。我已经研究了stackoverflow,但是没有一个对我有用。 任何人都可以帮助确定使用AngularJS

  • 这两个函数是否重载

  • 问题内容: 我有这个模块,它将外部库与其他逻辑一起组成组件,而无需将标签直接添加到index.html中: 我注意到ES6规范是静态的,并且在TypeScript编译期间而不是在运行时进行了解析。 无论如何使其可配置,以便从CDN或本地文件夹加载file.js?如何告诉Angular 2动态加载脚本? 问题答案: 如果使用的是system.js,则可以在运行时使用: 如果您使用的是webpack,

  • 问题内容: 我正在构建Java Web应用程序,并且我讨厌传统的“代码-编译-部署-测试”周期。我想输入一个微小的更改,然后立即查看结果,而无需编译和部署。 幸运的是,码头很适合这样做。这是一个纯Java Web服务器。它带有一个非常不错的maven插件,可让您直接从构建树中启动Jetty阅读- 无需打包war文件或部署。它甚至具有scanInterval设置:将其设置为非零值,它将监视您的Jav