Angular 2+服务继承:是否需在父类与子类重复注入服务?
问题
我有一个继承自父类的组件,该父类已注入MyService服务,且子类组件也需使用此服务。请问是否必须在父类和子类中重复导入并注入该服务?这对我而言属于代码冗余,且子类需导入服务以传递给已导入该服务的父类,逻辑略显矛盾。
原代码示例
子类(app.component.ts)
import { Component, OnInit } from '@angular/core'; import { HelperClass } from 'src/app/helper-class'; /**** 与父类HelperClass重复导入 ****/ import { MyService } from 'src/app/my-service.service'; @Component({ selector: 'app-my-component', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) export class MyComponent extends HelperClass implements OnInit { /**** 与HelperClass重复注入 ****/ constructor(private service: MyService) { super(service); } ngOnInit(): void { this.myService.log('my service called in MyComponent'); this.helper_class_method(); } }
父类(helper-class.ts)
import { MyService } from 'src/app/my-service.service'; export class HelperClass { constructor(public myService: MyService) { } helper_class_method() { console.log('helper_class method'); } }
服务(my-service.service.ts)
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class MyService { log(text: string) { console.log(text); } }
解决方案
不需要在子类中重复导入和注入MyService,可以通过两种方式消除冗余:
方式一:简化子类构造函数,复用父类的public服务实例
父类已经将myService声明为public,子类继承后可直接访问该属性。子类构造函数只需注入服务并传递给父类,无需重复声明私有属性:
import { Component, OnInit } from '@angular/core'; import { HelperClass } from 'src/app/helper-class'; // 保留导入用于TypeScript类型检查,避免类型报错 import { MyService } from 'src/app/my-service.service'; @Component({ selector: 'app-my-component', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) export class MyComponent extends HelperClass implements OnInit { constructor(service: MyService) { super(service); } ngOnInit(): void { this.myService.log('my service called in MyComponent'); this.helper_class_method(); } }
方式二:父类用@Inject直接获取服务,子类无需传递依赖
如果父类是普通类(非组件),可以使用Angular的@Inject装饰器直接在父类中注入服务,子类构造函数无需传递任何参数:
修改后的父类代码
import { Inject } from '@angular/core'; import { MyService } from 'src/app/my-service.service'; export class HelperClass { constructor(@Inject(MyService) public myService: MyService) { } helper_class_method() { console.log('helper_class method'); } }
修改后的子类代码
import { Component, OnInit } from '@angular/core'; import { HelperClass } from 'src/app/helper-class'; // 此时子类无需导入MyService(除非需要显式使用类型) @Component({ selector: 'app-my-component', templateUrl: './app.component.html', styleUrls: ['./app.component.sass'] }) export class MyComponent extends HelperClass implements OnInit { constructor() { super(); } ngOnInit(): void { this.myService.log('my service called in MyComponent'); this.helper_class_method(); } }
核心说明
- 当父类是普通类时,Angular不会自动处理其依赖注入,需通过
@Inject显式声明或在子类中传递依赖;若父类是组件类,Angular会自动处理依赖,但子类仍需调用super()并传递必要参数。 - 利用父类的
public修饰符,子类可直接继承并访问服务实例,彻底避免重复注入的冗余问题。
内容的提问来源于stack exchange,提问作者manuch100
相关产品推荐
相关产品推荐

