【问题标题】:No provider for "NgComponentOutlet"“NgComponentOutlet”没有提供者
【发布时间】:2021-05-06 18:16:56
【问题描述】:

我有一个 Angular 11 应用程序,它导入 @angular/material@ngx-translate 和一个名为 icell-data-table 的库。

从 github 页面下载示例项目,我能够在本地环境中没有任何问题的情况下启动它。

但在将其提取到 Stadckblitz 演示时,我遇到了一个奇怪的错误:

Error in /turbo_modules/@angular/compiler@11.1.1/bundles/compiler.umd.js (3057:21)
Template parse errors:
No provider for NgComponentOutlet ("onentTemplate [cellTemplate]="'componentTemplate'" let-row="row" let-col="col" let-idx="rowIdx">
[ERROR ->]<ng-container
*ngComponentOutlet="col.component; ndcDynamicInputs: getComponentInputs(row, col);"): ng:///DataTableModule/CellTemplatesComponent.html@23:2

Stackblitz project can be found here。关于它缺少什么的任何想法?

更新 1: 正如@yurzui 指出的那样,icell-data-table 和 Angular 11 中存在不兼容的依赖关系。我已将具有适当依赖关系的库更新为 ng-dynamic-component,现在是 Angular11 版本 (^8.0.0)。

但是 stackblitz 示例仍然显示错误:(

【问题讨论】:

  • 检查两个环境下所有依赖和配置的版本是否同步

标签: angular ng-component-outlet


【解决方案1】:

这里的问题是,在 stackblitz 中你有两个版本的 @angular/common 包。

@angular/common@11.1.1
@angular/common@9.1.13

前者在 Angular 注册提供者时使用,后者在需要解析提供者时发挥作用。

让我们看看为什么 Angular 无法解析 NgComponentOutlet 令牌。这里有一个简单的解释:

import { NgComponentOutlet as outlet1 } from "@angular/common@11.1.1";
import { NgComponentOutlet as outlet2 } from "@angular/common@9.1.3";
 

const providers = new Map();
providers.set(outlet1, 'Any value');

console.log(providers.has(outlet2)); // false

NgComponentOutlet 类在两个包中都定义了,它们甚至看起来一样,但是由于 Angular 使用 Map 对象来解析提供程序,因此由于 Map 中的键相等性基于 sameValueZero algorithm 而失败

现在,为什么我们在 stackblitz 中有两个版本的 Angular 包。那是因为@i-cell/data-table 使用ng-dynamic-component@6.1.0 哪个depends on Angular 9

所以,一旦你解决了这个版本的不兼容问题,你应该得到类似 Forked Stackblitz

【讨论】:

  • 我将在下周查看上述库并正确更新依赖项,您指出这一点真是太棒了!只是为了好奇:您能告诉我您在分叉示例中究竟更新了什么以使其在当前状态下工作?
  • 我拦截了保存 http 请求并替换了不兼容的依赖项
  • 我已经更新了icell-data-table 项目以依赖ng-dynamic-component@8.0.1 的正确版本,并发布了新版本的库。但是,问题仍然存在:(
  • 现在的问题是 stackblitz 将 ng-dynamic-component 的依赖关系解析为 @angular/common@11.1.2 但您正在运行 11.1.1 版本。
  • stackblitz.com/edit/… 我将@angular/core@angular/common 更新到11.1.2,将AppComponent 选择器替换为my-app 并将RouterModule.forRoot([])添加到root NgModule
猜你喜欢
  • 2017-08-13
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多