"NgComponentOutlet" 没有供应商

No provider for "NgComponentOutlet"

我有一个 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 中存在不兼容的依赖关系。我已经将 lib 更新为 ng-dynamic-component,现在是 Angular11现在的版本 (^8.0.0)。

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

这里的问题是在 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 class 在两个包中都有定义,它们甚至看起来相同,但由于 Angular 使用 Map 对象来解析提供程序,因此由于 Map 键相等是基于 sameValueZero algorithm

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

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