如何使用 angular 2 中的依赖项扩展服务
how to extend service with dependencies in angular 2
我有一个父服务,它有一些依赖关系,比如
@Injectable()
export class ParentService{
constructor(private http:Http, private customService:CustomService){}
}
我想延长服务
@Injectable()
export class ChildService extends ParentService{
constructor (){
super(??) <= typescript now asking to enter two parameters according to ParentServie's constructor
}
}
编辑----------------
@Injectable()
export class ParentService{
constructor(private http:Http, private customService:CustomService){}
get(){this.http.get(...)}
}
@Injectable()
export class ChildService extends ParentService{
constructor (private http:Http, private customService:CustomService){
super(http, customService)
}
}
那我可以在组件中使用吗?
export class Cmp {
constructor(private childService:ChildService){
this.childService.get()
}
}
super的参数class需要重复传递给super调用:
@Injectable()
export class ChildService extends ParentService{
constructor (http:Http, customService:CustomService){
super(http, customService);
}
}
有一些 "hacks" 可以解决,例如
干脆做基服……非@Injectable()
!例如,您需要提供一种方法来检索 LoginService
中的用户配置文件。对于LoginService
的不同实例,这个方法会有所不同,parent class一定不知道这个方法从哪里来的:它可以是lambda,可以是导出函数,它可以是另一个服务的方法。为此,您可以声明 parent 服务
Parent 服务:
// Don't annotate it with @Injectable() ! It's a simple class.
export abstract class BaseLoginService {
constructor(
// This won't be injected automatically,
// child class must call super() and provide value for this argument.
// Note: it's private, can't be accessed outside of BaseLoginService class
private http: HttpClient,
// Method used to retrieve user profile
private profileGetter: () => Observable<UserDetails>,
private router: Router
) {
this.profileGetter().subscribe(); // Do something with this method
}
然后在child中扩展它 class:
// Child class must be annotated with @Injectable(),
// if you don't need to extend it further
@Injectable()
export class LoginService extends BaseLoginService {
constructor(
// Note: no public/private/protected here - "http"
// will be just an argument
http: HttpClient,
private profileService: ProfileService, // This is the private field of LoginService class
router: Router,
// Some service used by LoginService class, parent class BaseLoginService
// doesn't need to know about SomeOtherService
private someOtherService: SomeOtherService
) {
super(
http,
// Need lambda here to capture profileService instance. If
// profileService.getUserDetailsMethod doesn't use instance
// fields or methods, then we can simply write
// "profileService.getUserDetailsMethod" (without quotes, obviously).
() => profileService.getUserDetailsMethod(),
router
);
this.someOtherService.doSomething(); // Custom initialization code
}
注意:在模块的 providers
部分指定 LoginService
而不是 parent BaseLoginService
:
providers: [
LoginService,
并在组件 classes:
中使用它
export class LoginComponent implements OnInit {
constructor(
private loginService: LoginService
) {
}
如果您需要使用 parent 服务(例如,在只需要 parent 服务 class 的功能的共享组件中),则以这种方式提供 BaseLoginService
:
providers: [
{provide: BaseLoginService, useExisting: LoginService}, // For those components which need functionality from base class only
LoginService, // Still need this one for those components which need functionality from child class
如果在抽象classprotected
中做DI服务,而在subclass中省略构造函数,那么subclass中的服务是可用的.
我有一个父服务,它有一些依赖关系,比如
@Injectable()
export class ParentService{
constructor(private http:Http, private customService:CustomService){}
}
我想延长服务
@Injectable()
export class ChildService extends ParentService{
constructor (){
super(??) <= typescript now asking to enter two parameters according to ParentServie's constructor
}
}
编辑----------------
@Injectable()
export class ParentService{
constructor(private http:Http, private customService:CustomService){}
get(){this.http.get(...)}
}
@Injectable()
export class ChildService extends ParentService{
constructor (private http:Http, private customService:CustomService){
super(http, customService)
}
}
那我可以在组件中使用吗?
export class Cmp {
constructor(private childService:ChildService){
this.childService.get()
}
}
super的参数class需要重复传递给super调用:
@Injectable()
export class ChildService extends ParentService{
constructor (http:Http, customService:CustomService){
super(http, customService);
}
}
有一些 "hacks" 可以解决,例如
干脆做基服……非@Injectable()
!例如,您需要提供一种方法来检索 LoginService
中的用户配置文件。对于LoginService
的不同实例,这个方法会有所不同,parent class一定不知道这个方法从哪里来的:它可以是lambda,可以是导出函数,它可以是另一个服务的方法。为此,您可以声明 parent 服务
Parent 服务:
// Don't annotate it with @Injectable() ! It's a simple class.
export abstract class BaseLoginService {
constructor(
// This won't be injected automatically,
// child class must call super() and provide value for this argument.
// Note: it's private, can't be accessed outside of BaseLoginService class
private http: HttpClient,
// Method used to retrieve user profile
private profileGetter: () => Observable<UserDetails>,
private router: Router
) {
this.profileGetter().subscribe(); // Do something with this method
}
然后在child中扩展它 class:
// Child class must be annotated with @Injectable(),
// if you don't need to extend it further
@Injectable()
export class LoginService extends BaseLoginService {
constructor(
// Note: no public/private/protected here - "http"
// will be just an argument
http: HttpClient,
private profileService: ProfileService, // This is the private field of LoginService class
router: Router,
// Some service used by LoginService class, parent class BaseLoginService
// doesn't need to know about SomeOtherService
private someOtherService: SomeOtherService
) {
super(
http,
// Need lambda here to capture profileService instance. If
// profileService.getUserDetailsMethod doesn't use instance
// fields or methods, then we can simply write
// "profileService.getUserDetailsMethod" (without quotes, obviously).
() => profileService.getUserDetailsMethod(),
router
);
this.someOtherService.doSomething(); // Custom initialization code
}
注意:在模块的 providers
部分指定 LoginService
而不是 parent BaseLoginService
:
providers: [
LoginService,
并在组件 classes:
中使用它export class LoginComponent implements OnInit {
constructor(
private loginService: LoginService
) {
}
如果您需要使用 parent 服务(例如,在只需要 parent 服务 class 的功能的共享组件中),则以这种方式提供 BaseLoginService
:
providers: [
{provide: BaseLoginService, useExisting: LoginService}, // For those components which need functionality from base class only
LoginService, // Still need this one for those components which need functionality from child class
如果在抽象classprotected
中做DI服务,而在subclass中省略构造函数,那么subclass中的服务是可用的.