Токен внедрения, не определенный в сервисе, но найденный в компоненте

#angular #typescript #dependency-injection

#angular #typescript #внедрение зависимости

Вопрос:

Я добавляю внешние js библиотеки как InjectionTokens в приложение Angular 7, чтобы использовать их в @Components службах. Я создал интерфейс, InjectionToken<> и Provider Provider , и добавил providers: [] в @NgModule свойство an, которое используется для этого.

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

Когда я внедряю InjectionToken в компонент, я могу использовать его отлично. Когда я пытаюсь внедрить его в сервис, я получаю ... is not defined ошибку.

angular.json :

 [...]

"scripts": [
    "./node_modules/hot-formula-parser/dist/formula-parser.js",
    "./node_modules/@handsontable/formulajs/dist/formula.js"
]

[...]

  

entry.module.ts :

 import { NgModule, InjectionToken } from '@angular/core';
import { CommonModule } from '@angular/common';
import { EntryComponent } from './entry.component';
import { RouterModule } from '@angular/router';
import { entryRoutes } from './entry.routes';
import { SharedModule } from 'src/shared/shared.module';
import { EntryService } from './entry.service';
import { HotParserProvider} from './parser/parser.injector';

@NgModule({
    declarations: [EntryComponent],
    imports: [SharedModule, CommonModule, RouterModule.forChild(entryRoutes)],
    exports: [],
    providers: [
        HotParserProvider,
        EntryService, 
    ],
})
export class EntryModule { }
  

parser.injector.ts :

 import { InjectionToken, ValueProvider } from "@angular/core";

interface IHotParser {
    parse: (formula: string) => {error:string, result: any};
}

const HotParser: InjectionToken<IHotParser> = new InjectionToken<IHotParser>('HotParser');

const HotParserProvider: ValueProvider = {
    provide: HotParser,
    useValue: new window['formulaParser'].Parser()
}

export {IHotParser, HotParser, HotParserProvider};
  

entry.component.ts :

 import { Component, Inject } from '@angular/core';
import { EntryService } from './entry.service';
import { HotParser, IHotParser } from './parser/parser.injector';

@Component({
    selector: 'tp-entry',
    templateUrl: './entry.component.html',
    styleUrls: ['./entry.component.css']
})
export class EntryComponent {
    constructor(
        @Inject(HotParser) private parser: IHotParser, // No error!
        private entryService:EntryService
    ) { }

    ngOnInit(): void {
        console.log(parser.parse("SUM(1,1)"); // Correct output!       
    }
}
  

entry.service.ts :

 import { Injectable, Inject } from '@angular/core';
import { IHotParser} from './parser/parser.injector';

@Injectable()
export class EntryService {
    constructor(
        @Inject(HotParser) private parser: IHotParser // HotParser is not defined
    ) { }

  

Есть ли разница между введением токена в компонент и в сервис?
Я пытался изменить порядок массива поставщика модулей, но безрезультатно…

Ответ №1:

Неважно. Компоновка Visual Studio Code не предупредила меня о том, что HotParser не был импортирован в import инструкции службы… Я увидел следующую ошибку компилятора:

 ERROR in src/entry/entry.service.ts(11,25): error TS2304: Cannot find name 'HotParser'.
  

Так что в итоге изменилось:

 import { IHotParser } from './parser/parser.injector';
  

Для:

 import { HotParser, IHotParser } from './parser/parser.injector';
  

И ошибка исчезла.