typescript Angular :此类型不支持作为注入令牌

s4n0splo  于 2023-02-05  发布在  TypeScript
关注(0)|答案(3)|浏览(223)

我正在尝试创建一个类型为string的构造函数,但我得到的错误为:
不支持此类型作为注入令牌

@Injectable({providedIn: 'root'})
export class DataService {
     constructor(url:string, private http:HttpClient) { 
     }
}

export class PostService extends DataService {
    constructor(http:HttpClient) {
         super("https://jsonplaceholder.typicode.com/posts",http);
    }
 }
xmd2e60i

xmd2e60i1#

我相信您遇到的错误是:编译有问题:X

ERROR

src/app/services/data.service.ts:14:23 - error NG2003: No suitable injection token for parameter 'url' of class 'DataService'.
  Consider using the @Inject decorator to specify an injection token.

14   constructor(private url: string, private http: HttpClient) {}
                         ~~~

  src/app/services/data.service.ts:14:28
    14   constructor(private url: string, private http: HttpClient) {}
                                  ~~~~~~
    This type is not supported as injection token.

DataService类(由PostService扩展)不应是可注入的。可注入意味着该类(例如DataService)可作为依赖项提供和注入,不应是可注入的,因为其目的是提供形状或可重用服务(以避免在多个服务中编写相同的代码)
解决方案是注解掉DataService中的可注入装饰器

// @Injectable({
//   providedIn: 'root',
// })

export class DataService {
  constructor(private url: string, private http: HttpClient) {}

PostService应类似于:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

import { DataService } from './data.service';

@Injectable({
  providedIn: 'root',
})
export class PostService extends DataService {
  constructor(http: HttpClient) {
    super('https://jsonplaceholder.typicode.com/posts', http);
  }
}
iih3973s

iih3973s2#

问题在于,通过将DataService声明为@Injectable,所有构造函数参数都需要是可注入的,并且没有string值可注入。另外,相反,如果PostService没有声明为@Injectable,则PostService不会接收httpClient注入示例。
你可能不想在任何地方注入DataService,对吗?它的目标是成为一个抽象类,对吗?
如果是这样,您应该将具体类声明为@Injectable

export abstract class DataService {
     constructor(url:string, private http:HttpClient) { 
     }
}

@Injectable({providedIn: 'root'})
export class PostService extends DataService {
     constructor(http:HttpClient) {
         super("https://jsonplaceholder.typicode.com/posts",http);
     }
 }
mzillmmw

mzillmmw3#

据我所知,这是行不通的,因为构造函数只是用于依赖注入。
一般来说,我发现在Angular中子类化组件总是相当繁琐和脆弱,所以我会尽量完全避免它。委托/组合而不是继承。([edit]我刚看到这不是关于组件的,抱歉)
无论如何,如果你想坚持扩展,在你的特定情况下,下面的方法可能会起作用:

export abstract class AbstractDataService {
  constructor(private http: HttpClient) {}

  /** Provided by subclasses. */
  protected abstract getUrl(): string;
}

@Injectable({ providedIn: 'root' })
export class PostService extends AbstractDataService {
  protected getUrl(): string {
    return 'https://jsonplaceholder.typicode.com/posts';
  }
}

不要通过构造函数设置属性,而是通过在子类中实现的抽象方法提供属性。

相关问题