2

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

在将 Angular 应用程序变成混合应用程序之前,我确认它可以正常工作。在最初添加一个简单的 angularjs 混合启动模块后,angularjs 启动模块运行良好。

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

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

我需要做什么来确保将 ComponentFactoryResolver 提供给角度模块?

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)

这是启动 angularjs 模块的 angular 模块,并为 HelloAngularComponent 提供了与 downgradeComponent 一起使用的入口点。错误指向这个角度(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)!';
}   
4

1 回答 1

0

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

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

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

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

于 2018-05-02T20:29:15.947 回答