Angular Hybrid Error: Попытка получить инжектор AngularJS перед его установкой

Как использовать сервис AngularJS в компоненте Angular 5?

У меня есть приложение AngularJS, и я пытаюсь создать гибридное приложение, но не могу использовать AngularJS.

ОШИБКА Ошибка: Попытка получить инжектор AngularJS перед его установкой.

мой main.ts это

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);

app.module:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, InjectionToken } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { UpgradeModule, downgradeComponent } from '@angular/upgrade/static';
import { AppComponent } from './app.component';
import { SignInComponent } from "./modules/login/components/sign-in/sign-in.component";
import { authServiceProvider } from './shared/angularJS-upgraded-providers';



@NgModule({
    declarations: [
        AppComponent,
        SignInComponent
    ],
    imports: [
        BrowserModule,
        UpgradeModule,
        FormsModule
    ],
    entryComponents: [
        SignInComponent
    ],
    providers: [authServiceProvider],
    bootstrap: [SignInComponent]
})

export class AppModule {
    ngDoBootstrap() {}
}

angularJS-upgradeded-provider.ts:

import { InjectionToken } from "@angular/core";
export const AuthService = new InjectionToken<any>('authService');

export function authServiceFactory(i: any) {
  return i.get('authService');
}

export const authServiceProvider = {
  provide: AuthService,
  useFactory: authServiceFactory,
  deps: ['$injector']
};

и sign-in.component.ts:

import { Component, Inject } from '@angular/core';
import {AuthService} from "../../../../shared/angularJS-upgraded-providers";

@Component({
    selector: 'sign-in',
    template: require('./sign-in.component.html')
})

export class SignInComponent {
    constructor(
        @Inject(AuthService) private authService: any) {
    }
}

Когда я удаляю код части конструктора Sign InComponent, он хорошо компилируется, но с @Inject(AuthService) private authService: любая) { } часть, я получаю ошибку:

Попытка получить инжектор AngularJS, прежде чем он будет установлен.

Пожалуйста, дайте мне несколько советов, как я могу реализовать AngularJS сервис Insight Angular. Спасибо

PS мой пакет.json:

{
  "name": "test",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "start": "webpack-dev-server --port=4200 --open chrome"
  },
  "dependencies": {
    "@angular/common": "^5.2.11",
    "@angular/compiler": "^5.2.11",
    "@angular/core": "^5.2.11",
    "@angular/forms": "^5.2.11",
    "@angular/http": "^5.2.11",
    "@angular/platform-browser": "^5.2.11",
    "@angular/platform-browser-dynamic": "^5.2.11",
    "@angular/router": "^5.2.11",
    "@angular/upgrade": "^5.2.11",
    "core-js": "^2.5.7",
    "reflect-metadata": "^0.1.12",
    "rxjs": "^5.5.11",
    "zone.js": "^0.8.26"
  },
  "devDependencies": {
    "@types/jquery": "^3.3.6",
    "@types/node": "^8.10.23",
    "awesome-typescript-loader": "^5.2.0",
    "css-loader": "^1.0.0",
    "html-loader": "^0.5.5",
    "html-webpack-plugin": "^3.2.0",
    "raw-loader": "^0.5.1",
    "style-loader": "^0.22.1",
    "ts-loader": "3.2.0",
    "typescript": "^2.9.2",
    "webpack": "^4.16.5",
    "webpack-cli": "^3.1.0",
    "webpack-dev-server": "^3.1.5"
  }
}

И AngularJS версия: 1.6.8

0 ответов

Это означает, что вы подключаете зависимость AngularJS где-нибудь в дереве компонентов. Это может быть ваш непосредственный компонент или какая-то зависимость дальше по линии.

Для отладки:

Способ 1

Добавить debugger заявление непосредственно перед вашим bootstrap вызов:

it('should render the component', () => {
   debugger;
   bootstrap(Ng2AppComponent);
   ...
 });
  1. Открыв консоль JS, позвольте тесту выполнить и приостановить его в месте расположения отладчика.
  2. Щелкните значок "Стоп / Пауза" (на боковой панели на вкладке "Источники") и установите флажок "Пауза при исключениях". Выключите отладчик.
  3. Отладчик должен остановиться при вызове injectorFactory. Используйте проводник стека, чтобы найти вызовыresolveNgModuleDep. Они будут рекурсивными, поэтому вершина стека будет ближе к листовому узлу, а вызовы дальше по стеку будут ближе к тестируемому компоненту. Ищите строки вроде:tokenKey = "ServiceName". Возможно, это ваша оскорбительная услуга.
  4. Погрузитесь в стек еще на один уровень, чтобы узнать, какой компонент пытался внедрить эту службу.
  5. В рамках вашего теста смоделируйте поставщика для обработки этой конкретной инъекции. Обратите внимание, что этот код предполагает только одну инъекцию проблемы. В случае возникновения нескольких проблем с форсунками вам потребуется в особом случае:
 beforeEach(() => {
   setupModule({
     imports: [
       ...
     ],
     providers: [
       {
         provide: '$injector',
         useValue: {
           get: () => {
             return new MockService();  // enhance as needed
           },
         }
       }
     ],
   });

Способ 2

  1. Макет провайдера для $injector вызвать и вернуть пустой объект.
beforeEach(() => {
   setupModule({
     imports: [
       ...
     ],
     providers: [
       {
         provide: '$injector',
         useValue: {
           get: (serviceName?: string) => {
            console.log('looking for serviceName:', serviceName);
            return {};  // this will break things differently
           },
         }
       }
     ],
   });
  1. Посмотрите на вывод консоли, чтобы найти проблемную службу / подпись. Это может потребовать, а может и не потребовать меньше работы, чем метод 1.
Другие вопросы по тегам