Angular: этот тип не поддерживается в качестве токена инъекции.

avatar
Ziyad hr
1 июля 2021 в 17:41
1615
3
0

Я пытаюсь создать конструктор с типом 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);
    }
 }
Источник

Ответы (3)

avatar
Youssef
4 января 2022 в 08:35
0

Я полагаю, что ошибка, с которой вы столкнулись, такова: Скомпилировано с проблемами: 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) доступен для предоставления и внедрения в качестве зависимости, чего не должно быть, поскольку его целью является предоставление формы или службы многократного использования (во избежание написания одного и того же кода в нескольких службах)

решение состоит в том, чтобы закомментировать декоратор Injectable в 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);
  }
}
avatar
Gaël J
1 июля 2021 в 18:26
0

Проблема в том, что при объявлении DataService как @Injectable все параметры конструктора должны быть вводимыми, а значение string не может быть вставлено. Кроме того, наоборот, PostService не получит экземпляр httpClient, если он не объявлен как @Injectable.

.

Вероятно, вы не хотите иметь возможность вводить 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);
     }
 }
avatar
qqilihq
1 июля 2021 в 17:49
0

Насколько мне известно, это не сработает, так как конструктор просто используется для внедрения зависимостей.

Вообще, я находил подклассы компонентов в 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';
  }
}

Вместо того, чтобы задавать свойство с помощью конструктора, укажите его с помощью абстрактного метода, который вы реализуете в своих подклассах.