Angular 7 - Доступ к сервису возвращается неопределенным в наблюдаемом - PullRequest
0 голосов
/ 23 апреля 2019

Я работаю со службой, которая реализует глобальную службу под названием AppService, которая хранит некоторые глобальные конфигурации приложений.

Для начала я опубликую здесь некоторые из моих кодов:

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector, APP_INITIALIZER } from '@angular/core';
import { AppService } from './app.service';

...

export function appLoadConfig(appService: AppService) {
  return () => appService.loadConfig();
}

@NgModule({
  imports: [
    BrowserModule,
    CoreModule,
    ...
  ],
  declarations: [
    AppComponent,
  ],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: appLoadConfig,
      deps: [ AppService ],
      multi: true
    }
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

app.service.ts

import { Injectable, ... } from '@angular/core';

...

@Injectable({
  providedIn: 'root'
})
export class AppService {

  loadConfig(): Promise<any> { ... }

}

file.service.ts

import { Injectable } from '@angular/core';
import { AppService } from '../../app.service';
...

@Injectable()
export class FileService {

  filesChange: BehaviorSubject<FileNode[]> = new BehaviorSubject<FileNode[]>([]);

  constructor(
    private appService: AppService,
    private httpClient: HttpClient) { }

  changeListType(types: string[]) {
    this._getAllFiles();
  }

  private _getAllFiles() {
    this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
        .subscribe(this._publishData);
  }

  private _publishData(data: FileNode[]) {
    let nodeData: FileNode[] = [];
    data.forEach((n: any) => {
      const node = new FileNode(n);
      node.fullPath = `${this.appService.config.api}/uploads/${node.uri}`;
      nodeData.push(node);
    });
    this.filesChange.next(nodeData);
  }
}

Когда в компоненте, который я вызываю метод changeListType из file.service, он извлекает данные, но метод _publishData показывает, что this.appService, использованный для построения node.fullPath, не определен. Если я изменю вызов в подписчике метода _getAllFiles на этот:

this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
            .subscribe((data: any) => { this._publishData(data); });

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

Заранее спасибо.

1 Ответ

3 голосов
/ 23 апреля 2019

У вас проблема с областью действия this:

Во втором подходе вы не получаете appService как неопределенное, потому что вы ссылаетесь на функцию _publishData из функции стрелки. Функции стрелок не создают свои собственные this и используют this из своей внешней области видимости. Когда в этом случае вызывается функция _publishData, то this, на который она ссылается, является this компонента, а не this

функции

Подробнее о функциях стрелок здесь .

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

Вам необходимо связать правильное значение с _publishData функцией

  private _getAllFiles() {
    this.httpClient.get<any>(`${this.appService.config.api}/api/files/`)
        .subscribe(this._publishData.bind(this));
  }
...