【问题标题】:Can't access property of existing service in component无法访问组件中现有服务的属性
【发布时间】:2019-05-06 19:42:32
【问题描述】:

我创建了一个服务简单服务,它首先从 JSON 文件加载配置。因为我希望在应用程序启动时数据可用,所以我使用 APP_INITIALIZER 来加载数据。

在服务本身中,数据可用,一切都很好。但是,当我从组件内部使用该服务时,它会出现奇怪的行为。请问有人可以解释我的代码有什么问题吗?

filterService.ts

export class FilterService {
   url:string = '/admin2/src/assets/import.filter.json';
   filters: Filter[];
   currentFilter: Filter;

   public loadFilters() {

      this.http.get(this.url).subscribe(response => {
        this.filters = <Filter[]>response;

        if (this.filters[0])
            this.currentFilter  = this.filters[0];
    });
}

此服务在应用程序初始化期间加载

app.module.ts

 @NgModule({
 ...
 providers: [
    FilterService,
    { provide: APP_INITIALIZER, useFactory: (filterService: FilterService) => () => filterService.loadFilters(), deps: [FilterService], multi: true },
 ],
 ...

最后,在我正在做的组件中:

filter.component.ts

constructor(private filterService: FilterService) {}

ngOnInit() { 
    console.log('import initialized'); 

    console.log(this.filterService);
    console.log(this.filterService.currentFilter);
    console.log(this.filterService.filters);
    console.log(this.filterService.getFilters());
}

现在我真的不明白 console.log 中发生了什么

  Object { http: {…}, url: "http://...}   // as expected
  undefined                               // ??                               
  undefined                               // ??
  undefined                               // ??

为什么我无法访问对象属性?在我看来,一切都很好并且可用....

【问题讨论】:

  • 您应该在服务文件中“返回 this.http.get(this.url)”...以及在 component.ts 文件中:您应该订阅...您的原因变得未定义是因为异步代码尚未完成加载,并且您尝试打印该值...在 stackblitz 上创建一个示例,如果您遇到困难,有人会指导您完成
  • 我明白,这也是我的第一个方法。但最后我希望在不使用 subscribe() 的情况下在服务中提供数据。一般来说,输出对我来说很奇怪:一方面,colsole.log() 向我显示了对象,但一旦我尝试访问属性,它就未定义。我以前从未见过这样的行为......
  • 如果你创建了一个 stackblitz,sO 社区可以帮助确定原因......

标签: angular service constructor components


【解决方案1】:

在你的情况下 =>

app-load.module.ts

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { HttpClientModule } from "@angular/common/http";

import { FilterService } from './filter.service';

export function load_filters(filterService: FilterService) {
    return () => filterService.loadFilters();
}

export function get_filters(filterService: FilterService) {
    return () => filterService.getFilters();
}

@NgModule({
  imports: [HttpClientModule],
  providers: [
    AppLoadService,
    { provide: APP_INITIALIZER, useFactory: load_filters, deps: [FilterService], multi: true },
    { provide: APP_INITIALIZER, useFactory: get_filters, deps: [FilterService], multi: true }
  ]
})
export class AppLoadModule { }

app.module.ts

import { AppLoadModule } from './app-load/app-load.module';
@NgModule({
     imports: [AppLoadModule]
 })

我已关注此博客来创建我的 APP_INITIALIZER => 请阅读一次(可能有用) https://www.intertech.com/Blog/angular-4-tutorial-run-code-during-app-initialization/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    • 1970-01-01
    • 2020-06-17
    • 2018-02-10
    • 2020-08-02
    • 1970-01-01
    • 2014-02-01
    相关资源
    最近更新 更多