Angular组件降级为AngularJS时的依赖注入错误
解决Angular5降级组件无法注入Angular服务的问题
你在AngularJS到Angular5的混合升级中碰到了一个典型的跨注入器问题——降级后的Angular组件默认会在AngularJS的注入器上下文里运行,而你的Angular服务只注册在Angular自己的注入器中,所以才会出现注入失败的情况。下面给你两种靠谱的解决思路:
思路一:把Angular服务也降级为AngularJS可识别的服务
这种方式适合需要在AngularJS代码里也复用这个服务的场景,步骤如下:
- 先确认你的Angular服务已经在Angular模块中正确提供:
@Injectable({ providedIn: 'root' // 或者在AppModule的providers数组里声明 }) export class MyAngularService { getData(): string { return "来自Angular服务的数据"; } }
- 在混合应用的启动代码中,用
downgradeInjectable把Angular服务转成AngularJS工厂,并注册到AngularJS模块里:
import { downgradeInjectable } from '@angular/upgrade/static'; import { MyAngularService } from './services/my-angular.service'; // 假设你的AngularJS模块名叫angularJsApp angular.module('angularJsApp') .factory('myAngularService', downgradeInjectable(MyAngularService) as any);
- 回到你的Angular组件,现在可以直接注入这个降级后的服务(注意要使用Angular的
@Inject装饰器指定AngularJS里的服务名称):
import { Component, Inject } from '@angular/core'; import { MyAngularService } from './services/my-angular.service'; @Component({ selector: 'my-angular-comp', template: '<h3>{{serviceData}}</h3>' }) export class MyAngularComponent { serviceData: string; constructor(@Inject('myAngularService') private myService: MyAngularService) { this.serviceData = myService.getData(); } }
思路二:在降级组件中直接使用Angular注入器获取服务
如果这个服务只需要在Angular组件内部使用,不需要在AngularJS代码里调用,那可以直接用Angular的Injector来获取服务,绕开AngularJS的注入器:
- 在Angular组件中注入
Injector,然后通过它获取你的Angular服务:
import { Component, Injector } from '@angular/core'; import { MyAngularService } from './services/my-angular.service'; @Component({ selector: 'my-angular-comp', template: '<h3>{{serviceData}}</h3>' }) export class MyAngularComponent { serviceData: string; constructor(private injector: Injector) { // 直接从Angular注入器中获取服务 const myService = this.injector.get(MyAngularService); this.serviceData = myService.getData(); } }
- 正常降级组件并注册到AngularJS模块即可:
import { downgradeComponent } from '@angular/upgrade/static'; import { MyAngularComponent } from './components/my-angular.component'; angular.module('angularJsApp') .directive('myAngularComp', downgradeComponent({ component: MyAngularComponent }) as angular.IDirectiveFactory);
额外检查项
- 确保你的Angular根模块已经导入了
UpgradeModule,并且在ngDoBootstrap方法中正确引导了AngularJS应用:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { UpgradeModule } from '@angular/upgrade/static'; import { MyAngularService } from './services/my-angular.service'; import { MyAngularComponent } from './components/my-angular.component'; @NgModule({ imports: [BrowserModule, UpgradeModule], declarations: [MyAngularComponent], providers: [MyAngularService], entryComponents: [MyAngularComponent] // 降级组件必须加入这个数组 }) export class AppModule { constructor(private upgrade: UpgradeModule) {} ngDoBootstrap() { this.upgrade.bootstrap(document.body, ['angularJsApp'], { strictDi: false }); } }
如果之前的错误是No provider for MyAngularService,那上面的方案应该能解决你的问题。
内容的提问来源于stack exchange,提问作者Sri
相关产品推荐
相关产品推荐

