能否在Angular 2+服务中使用Angular 1.x(AngularJS)服务?
在Angular 2+服务中使用AngularJS服务的问题解析
我来帮你拆解这个问题——在Angular 2+服务里用AngularJS服务完全是可行的,你遇到的Trying to get the AngularJS injector before it being set报错,核心原因是注入器的初始化时机不匹配:
为什么组件里能用,服务里不行?
- Angular组件通常是在应用启动后、路由激活或者视图渲染阶段才会被实例化,这时候AngularJS的注入器已经通过
UpgradeModule完成初始化并传递给Angular侧了,所以能正常获取到AngularJS服务。 - 但Angular服务的实例化时机更早,可能在
UpgradeModule还没完成AngularJS应用的bootstrap、注入器还没准备好的时候就被创建了,自然就会抛出这个错误。
下面给你两个靠谱的解决方案:
方案1:延迟获取AngularJS服务(推荐)
不要在服务的构造函数里直接注入AngularJS服务,而是注入Angular的Injector,在实际需要使用服务的方法里再动态获取:
import { Injectable, Injector } from '@angular/core'; import { UpgradeModule } from '@angular/upgrade/static'; @Injectable({ providedIn: 'root' }) export class A2Service { private a1Service: any; constructor(private injector: Injector) {} // 当需要使用a1Service时再去获取 callA1ServiceMethod() { if (!this.a1Service) { // 先拿到AngularJS的注入器 const ng1Injector = this.injector.get(UpgradeModule).injector; this.a1Service = ng1Injector.get('a1Service'); } // 调用AngularJS服务的方法 return this.a1Service.yourMethod(); } }
这种方式避开了构造函数阶段的时机问题,只有在真正用到服务的时候才去获取注入器,确保此时注入器已经就绪。
方案2:通过APP_INITIALIZER确保注入器就绪
如果你还是想在服务构造函数里直接注入AngularJS服务,可以通过APP_INITIALIZER来强制AngularJS应用先完成bootstrap,再初始化你的Angular服务:
- 先写一个初始化函数,负责启动AngularJS应用:
export function bootstrapNg1App(upgrade: UpgradeModule) { return () => upgrade.bootstrap(document.body, ['yourAngularJSAppModuleName']); }
- 在AppModule里配置
APP_INITIALIZER和AngularJS服务的提供者:
import { NgModule, APP_INITIALIZER } from '@angular/core'; import { UpgradeModule } from '@angular/upgrade/static'; import { A2Service } from './a2.service'; // 你的getA1Service工厂函数调整为依赖UpgradeModule function getA1Service(upgrade: UpgradeModule) { return upgrade.injector.get('a1Service'); } @NgModule({ declarations: [...], imports: [UpgradeModule, /* 其他Angular模块 */], entryComponents: [...], providers: [ A2Service, // 确保AngularJS应用先启动 { provide: APP_INITIALIZER, useFactory: bootstrapNg1App, deps: [UpgradeModule], multi: true }, // 现在可以安全地提供a1Service了 { provide: 'a1Service', useFactory: getA1Service, deps: [UpgradeModule] } ] }) export class AppModule {}
APP_INITIALIZER会在应用启动前执行指定的工厂函数,完成AngularJS的bootstrap,确保注入器已经设置完成,之后再实例化你的A2Service时,就能正常获取到a1Service了。
额外提醒
- 尽量避免在Angular服务的构造函数中直接依赖AngularJS服务,构造函数的执行时机通常太早,容易踩初始化顺序的坑。
- 混合应用中,尽量保持AngularJS和Angular服务的职责边界清晰,减少跨版本的服务依赖,能让你的代码更易维护。
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

