StaticInjectorError(AppModule) 没有提供 ComponentFactoryResolver

StaticInjectorError(AppModule) no provider for ComponentFactoryResolver

我有一个可用的 rails 5.2.0 webpacker 应用程序,其中有一个最小的 angularjs 应用程序通过 angular AppModule 启动,使用 UpgradeModule.bootstrap 函数。

我确认 angular 应用程序在将其转换为混合应用程序之前工作正常。在最初添加一个简单的 angularjs 混合启动模块后,angularjs 启动模块 运行 很好。

我现在正在尝试使用 downgradeComponent 在启动的 angularjs 根模板中挂起一个 angular 组件,遵循此处的文档:

https://angular.io/guide/upgrade#using-angular-components-from-angularjs-code

我需要做什么来确保 ComponentFactoryResolver 被提供给 angular 模块?

angular 模块仍在启动 angularjs 模块,该模块仍在工作,但使用 downgradeComponent 函数的指令失败,控制台消息提示 angular声明组件的 AppModule 没有 ComponentFactoryResolver 的提供者。

angularjs:14961
Error: StaticInjectorError(AppModule)[ComponentFactoryResolver]: 
  StaticInjectorError(Platform: core)[ComponentFactoryResolver]: 
    NullInjectorError: No provider for ComponentFactoryResolver!
    at _NullInjector.get (core.js:1003)

这里是 angular 模块启动 angularjs 模块,并为 HelloAngularComponent 提供入口点以与 downgradeComponent 一起使用。错误指向此 angular (v5) 打字稿文件:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { UpgradeModule } from '@angular/upgrade/static';

import { HelloAngularComponent } from './hello_angular.component';

@NgModule({
  declarations: [
    HelloAngularComponent
  ],
  entryComponents: [
    HelloAngularComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule 
  ],  
  providers: [],
})
export class AppModule {
  constructor(private upgrade: UpgradeModule) { }
  ngDoBootstrap() {
    this.upgrade.bootstrap(document.body, ['hello_angularjs'], {strictDi: true});
  }
}

这里是 hello_angularjs/index.ts 模块被引导:

import angular from 'angular';
import uirouter from '@uirouter/angularjs';
import { HelloAngularComponent } from '../hello_angular/app/hello_angular.component';
import { downgradeComponent } from '@angular/upgrade/static';

angular.module('hello_angularjs', [uirouter])
  .controller('LoginMessage', ['$scope', function($scope) {
    'ngInject'; 
    $scope.message = 'Hello Angularjs';
  }])
  .config(['$stateProvider', ($stateProvider) => {
    'ngInject';
    $stateProvider
      .state('home', {
        url: '/',
        template: `<h1>hello_angularjs home template.</h1>
        <hello-angular>Loading Angular component downgraded to angularjs...</hello-angular>`
      })
  }])
  .directive(
    'helloAngular',
    downgradeComponent({ component: HelloAngularComponent }) as angular.IDirectiveFactory
  );

被降级的简单组件:

import { Component } from '@angular/core';

@Component({
  selector: 'hello-angular',
  template: `<h1>Hello {{name}}</h1>`
})
export class HelloAngularComponent {
  name = 'Angular (v5)!';
}   

我找到的一个解决方案是将 angularjs 引导模块移动到与 angular 5 模块相同的 webpack 包中。

使用 webpacker,这就像删除 app/javascripts/packs/hello_angularjs.js 一样简单,而是将 hello_angularjs 和 hello_angular index.ts 文件导入到由 [= 定义的同一个包中18=].js

import '../hello_angularjs'
import '../hello_angular'

我也可以将 angularjs 模块和指令调用合并到 @NgModule 代码所在的同一个 app.module.ts 文件中。