StaticInjectorError [HttpClent]: функция / класс не поддерживается - PullRequest
0 голосов
/ 01 мая 2018

Я пытаюсь ввести HttpClientModule вручную, который запускает вне независимо (может быть!) От приложения. До статического инжектора я использовал отражающий инжектор, и код работал нормально, но теперь этот отражающий инжектор устарел, и я хочу обновить свой код статическим инжектором.

//appInjector.ts
export class AppInjector {

  private static _instance: AppInjector = new AppInjector();
  private _injector;

  constructor() {
    console.log('app-injector');
    AppInjector._instance = this;
    this._injector = ReflectiveInjector.resolveAndCreate([
        ...[getAnnotations(HttpClientModule)[0].providers],
        MY_HTTP_DEPENDENT_PROVIDERS
        ]);
        
  static getInstance(): AppInjector {
    return AppInjector._instance;
  }

  get(cls: any): any {
    return this._injector.get(cls);
  }
}
//someFile.ts
const translate = AppInjector.getInstance().get(TranslateResource);

см. Это сообщение для аннотации фн. Теперь, когда я пытаюсь использовать Http-клиент со статическим инжектом, выдает ошибку: StaticInjectorError[HttpClent]: Function/class not supported

//app module
@NgModule({
  imports: [],
  declarations: [],
  providers: [],
  entryComponents: [App]
})
export class AppModule {
  ngDoBootstrap(app) {
    console.log('bootstrapping');
    app.bootstrap(App);
  }

, поэтому, если я войду в систему, он будет регистрировать app-injector, а затем bootstrapping.

1 Ответ

0 голосов
/ 01 мая 2018

StaticInjector должен заменить ReflectiveInjector, который не требует Reflect API. getAnnotations - хак низкого уровня и, скорее всего, не будет работать с StaticInjector в его текущем состоянии. Также, getAnnotations несовместимо с AOT по дизайну.

Желательно создать инжектор для модуля так, как это должно быть сделано фреймворком, то есть модуль должен быть загружен. Поскольку нет компонента для начальной загрузки, необходимо указать ngDoBootstrap hook.

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

Пример :

@NgModule({
  imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
  static httpClient?: HttpClient;
  httpClient?: HttpClient;

  constructor(private _injector: Injector) {}

  ngDoBootstrap() {
    MyHttpModule.httpClient = this.httpClient = this._injector.get(HttpClient);
  }  
}

platformBrowserDynamic().bootstrapModule(MyHttpModule)
.then((myHttpModule: NgModuleRef<MyHttpModule>) => {
    // HttpClient instance is available here
    const httpClient = myHttpModule.instance.httpClient;
    httpClient.get('/foo', { responseType: 'text'}).subscribe();
})
.catch(err => console.error(err));

Этот подход совместим как с JIT, так и с AOT (что хорошо для использования HttpClient отдельно от Angular, потому что это значительно уменьшает площадь) из коробки.

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

An пример :

@NgModule({
  imports: [BrowserModule, HttpClientModule]
})
export class MyHttpModule {
  static httpClient?: HttpClient;

  constructor(public _injector: Injector) {
    MyHttpModule.httpClient = this._injector.get(HttpClient);
  }

  ngDoBootstrap() {}  
}

const platform = platformBrowserDynamic();
const compiler = platform.injector.get(CompilerFactory).createCompiler();
const moduleFactory = compiler.compileModuleSync(MyHttpModule);

platform.bootstrapModuleFactory(moduleFactory)
.catch(err => console.error(err));

const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();

Это будет работать в JIT, но AOT не может быть эффективно обработан Angular CLI в приведенном выше коде. В коде используется компилятор, который не нужен в режиме компиляции AOT (в этом его цель). Чтобы использовать AOT, он должен быть скомпилирован с помощью ngc компилятора, и должна быть создана отдельная точка входа, которая использует фабрики модулей. Процедура начальной загрузки становится еще проще, потому что она не включает компилятор, что-то вроде:

...
import { platformBrowser } from '@angular/platform-browser-dynamic';
import { AppModuleNgFactory } from '<path to aot>/src/app/my-http-module.ngfactory';

const platform = platformBrowser();
platform.bootstrapModuleFactory(AppModuleNgFactory)
.catch(err => console.error(err));

const httpClient = MyHttpModule.httpClient;
httpClient.get('/foo').subscribe();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...