Angular 7-可观察到的服务访问未定义

时间:2019-04-23 12:00:06

标签: angular service observable

我正在使用一种服务,该服务实现了名为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用于构建{{ 1}}是未定义的。如果我将node.fullPath方法订户中的呼叫更改为此呼叫:

_getAllFiles

this.httpClient.get<any>(`${this.appService.config.api}/api/files/`) .subscribe((data: any) => { this._publishData(data); }); 变量不再是未定义的。这是故意的还是一种与范围变量有关的错误/错误?也许我的代码逻辑中缺少某些东西。

谢谢。

1 个答案:

答案 0 :(得分:3)

您对this的范围有疑问:

在第二种方法中,您没有得到appService的未定义状态,因为您是从箭头函数中引用_publishData函数的。 Arrow函数不会创建自己的this,而是从其外部范围使用this。在这种情况下,当调用_publishData函数时,它所引用的this是组件的this,而不是函数的this

详细了解箭头功能here

如果您不使用箭头功能,并且想要获得正确的订户功能this,则需要绑定this

您需要将正确的绑定到_publishData函数

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