Angular — можно ли использовать InjectionToken с компиляцией AOT?

В моем приложении объект конфигурации, который вводится из окна в приложение Angular. Для этого я разработал что-то в этом роде:

Код

Модель, представляющая конфигурацию

export class AppConfig {
    constructor(
        public apiKey: string,
        public username: string,
        public languageCode: string
    ) { }
}

Создание InjectionToken

import { InjectionToken } from '@angular/core';

import { AppConfig } from './shared';

export let APP_CONFIG = new InjectionToken<AppConfig>('appConfig');

Затем это предоставляется в AppModule

import { APP_CONFIG } from './app-config-export';
....
@NgModule({
    ....
    { provide: APP_CONFIG, useValue: (window as any).appConfig }
})

export class AppModule { }

Наконец внедрить его в компонент

import { AppConfig } from '../shared';
import { APP_CONFIG} from './app-config-export';

....

export class AppComponent implements OnInit {
     constructor(
         @Inject(APP_CONFIG) private appConfig: any,
         private appService: AppService
     ) { }

     ngOnInit() {
         this.appService.initApp(this.appConfig);
     }
}

Компиляция AOT

Это отлично работает, однако теперь я пытаюсь собрать приложение с помощью компиляции AOT. Когда я запускаю приложение с помощью AOT, appConfig всегда равно null. Я предполагаю, что это как-то связано с тем, как я ввожу конфигурацию, которая может быть несовместима с AOT. Есть ли способ заставить это работать с AOT?

Я нашел эту ветку на github https://github.com/angular/angular/issues/19154, однако я не понимаю, что подразумевается под «использовать вместо этого фабрику».

  • Угловой: 4.4.4
  • Веб-пакет: 3.8.1

Обновить

Я обновил AppModule следующим образом:

import { APP_CONFIG } from './app-config-export';
....

export function appConfigFactory() {
    return (window as any).appConfig;
}

@NgModule({
    ....
    { provide: APP_CONFIG, useFactory: appConfigFactory() }
})

export class AppModule { }

Решение

Я обновил AppModule следующим образом:

import { APP_CONFIG } from './app-config-export';
....

export function appConfigFactory() {
    return (window as any).appConfig;
}

@NgModule({
    ....
    { provide: APP_CONFIG, useFactory: appConfigFactory }
})

export class AppModule { }

Я вызывал функцию в обратном вызове useFactory вместо передачи функции.


person Daniel Grima    schedule 26.10.2017    source источник
comment
когда и где вы устанавливаете значение window.appConfig?   -  person Jota.Toledo    schedule 27.10.2017


Ответы (1)


Решение @Pankaj Parkar почти правильное, но вам также необходимо экспортировать обратный вызов useFactory, чтобы разрешить AoT:

import { APP_CONFIG } from './app-config-export';

export function configFactory() {
  return (window as any).appConfig;
}

@NgModule({
  providers: {
    provide: APP_CONFIG,
    useFactory: configFactory,
  }
})

В противном случае вы столкнетесь с этой ошибкой:

ERROR in Error: Произошла ошибка при статическом разрешении значений символов. Вызовы функций не поддерживаются. Рассмотрите возможность замены функции или лямбды ссылкой на экспортированную функцию...

person Martin Adámek    schedule 26.10.2017
comment
Я собирался написать то же самое :) Я только что попробовал код, однако конфиг теперь undefined вместо null - person Daniel Grima; 27.10.2017
comment
Где/когда вы устанавливаете window.appConfig? Похоже, что его просто нет, когда он нужен. - person Martin Adámek; 27.10.2017
comment
Конфигурация устанавливается до загрузки углового приложения. Я отлаживаю код, и когда я набираю window.appConfig в консоли, у меня есть значение. - person Daniel Grima; 27.10.2017
comment
Ну, тестировать это вживую через console не очень хорошая идея, так как вы делаете это уже после того, как возникла проблема. Попробуйте поставить console.log() в то место, где вы устанавливаете значение, а затем в то место, где вы пытаетесь его прочитать (на заводе). - person Martin Adámek; 27.10.2017
comment
Да, вы правы, код не входит на завод. Одна странная вещь, которую я заметил, заключается в том, что глядя на код после компиляции AoT, конструктор в AppComponent удаляет Inject(), поэтому вместо @Inject(APP_CONFIG) private appConfig: any у меня есть private appConfig: any - person Daniel Grima; 27.10.2017
comment
Обратите внимание, если он подключен, но почему у вас там тип any? Почему бы не использовать AppConfig? - person Martin Adámek; 27.10.2017
comment
Измените `useFactory: appConfigFactory()` ==› `useFactory: appConfigFactory` - person kemsky; 27.10.2017
comment
лол не видел этого в обновленном вопросе! да, вы должны передать эту ссылку на функцию, а не возвращаемое значение. - person Martin Adámek; 27.10.2017
comment
ха-ха, черт возьми, я не понял, я в полусне: D спасибо за вашу помощь, Кемски и Мартин :) это работает :) - person Daniel Grima; 27.10.2017