You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Angular 5组件中注入AngularJS服务?ngUpgrade迁移遇报错

解决AngularJS升级到Angular 5时注入AngularJS服务的错误

你遇到的Trying to get the AngularJS injector before it being set错误,核心原因是Angular组件的初始化早于AngularJS应用的引导完成。让我一步步帮你理清问题和解决方案:

为什么当前方法无效?

你现在的引导流程是先启动Angular的AppModule,再通过UpgradeModule启动AngularJS。但Angular的根组件AppComponent会在bootstrapModule完成后立刻初始化,这时候AngularJS的注入器还没被设置,导致依赖AngularJS服务的LoginPageComponent在构造函数里获取$injector时失败。

修复方案:调整引导顺序

我们需要确保AngularJS先完成引导,再初始化Angular组件。具体修改如下:

1. 修改app.module.ts

移除bootstrap数组,改用ngDoBootstrap手动控制引导顺序,同时把根组件加入entryComponents:

import { NgModule, ApplicationRef } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UpgradeModule } from '@angular/upgrade/static';
import { AppComponent } from './app.component';
import { LoginPageComponent } from './login.component';
import { authenticationServiceProvider } from './ajs-upgraded-providers';

@NgModule({
  declarations: [
    AppComponent,
    LoginPageComponent
  ],
  imports: [
    BrowserModule,
    UpgradeModule,
  ],
  providers: [
    authenticationServiceProvider,
  ],
  entryComponents: [AppComponent], // 手动引导需要加入这里
  // 移除自动引导的bootstrap数组
})
export class AppModule {
  constructor(private upgrade: UpgradeModule) {}

  ngDoBootstrap(appRef: ApplicationRef) {
    // 第一步:先引导AngularJS应用,确保注入器就绪
    this.upgrade.bootstrap(document.documentElement, ['myAngularJSApp']);
    // 第二步:再引导Angular根组件
    appRef.bootstrap(AppComponent);
  }
}

2. 简化main.ts

现在引导逻辑都在AppModule里了,main.ts只需要启动Angular模块即可:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

// 导入AngularJS模块
import '../ajs/app';

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch(err => console.error(err));

关于forwardRef的疑问

你提到的forwardRef其实和当前问题无关,它主要用于解决循环依赖场景(比如组件A依赖服务B,服务B又依赖组件A)。你的问题是注入器初始化顺序问题,所以不需要用到它。

更简化的服务升级方式

Angular的UpgradeModule提供了upgradeInjectable方法,可以帮你省去手动写factory的麻烦,直接把AngularJS服务升级为Angular服务:

修改ajs-upgraded-providers.ts:

import { upgradeInjectable } from '@angular/upgrade/static';
import { AuthenticationService } from '../ajs/services/authentication.service';

// 直接用upgradeInjectable关联AngularJS服务和Angular类
export const authenticationServiceProvider = upgradeInjectable({
  provide: AuthenticationService,
  useExisting: 'authentication' // 这里要和AngularJS中注册的服务名称完全一致
});

这样写和你之前的factory逻辑是等价的,但代码更简洁。

最后检查点

  • 确认AngularJS中注册的服务名称确实是'authentication'(和你在代码中$injector.get('authentication')的名称一致)
  • 确保AngularJS模块'myAngularJSApp'已经正确导入并注册了authentication服务

内容的提问来源于stack exchange,提问作者Stephan Muller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:13:34