angular - 服务相互包含时访问静态属性时出错

标签 angular typescript

按原样运行以下代码时,出现此错误:

未捕获的类型错误:无法读取未定义的属性“TYPE_CAMPAIGN”

Plunker Example

实体服务.ts

import {Injectable} from '@angular/core';
import {CampaignService} from './campaign/campaign.service';
import {TagService} from './tag/tag.service';

@Injectable()
export class EntityService {
  static TYPES = [
    CampaignService.TYPE_CAMPAIGN,
    TagService.TYPE_TAG
  ];
}

campaign.service.ts

import {Injectable} from '@angular/core';
import {EntityService} from '../entity.service';

@Injectable()
export class CampaignService {
  static TYPE_CAMPAIGN = 'campaign';

  constructor(private entityService: EntityService) {}

  public getTypes() {
    return EntityService.TYPES;
  }
}

标签.服务.ts

import {Injectable} from '@angular/core';
import {EntityService} from '../entity.service';

@Injectable()
export class TagService {
  static TYPE_TAG = 'tag';

  constructor(private entityService: EntityService) {}
}

但是,当我从 campaign.service.ts 中删除构造函数时,代码可以正常工作。为什么会报错,包含构造函数时如何访问静态属性?

更新 1: 在使用 Angular 的 Injector 进行测试以抵消加载类时,我发现在 CampaignService 的方法中访问 EntityService 的静态属性时仍然存在问题。我还发现在 campaign.service.ts 中添加 private entityService: EntityService 会导致问题。

更新 2:问题是由提供服务的模块中导入语句的顺序引起的(我最近按字母顺序排列了我的导入语句)。

应用程序模块.ts

import {CampaignService} from './campaign/campaign.service';
import {EntityService} from '../entity.service';
import {TagService} from './tag/tag.service';

@NgModule({
  providers: [
    CampaignService,
    EntityService,
    TagService
  ]
});

entity.service.ts 的导入语句移动到 campaign.service.ts 之前时,CampaignService 和 TagService 都可以正常工作。

更新 3: 看起来问题是特定于版本的。这是我当前使用的版本中发生的问题的示例:Example

如果您在查看控制台时切换 src/app.component.ts 中的导入语句,那么您将看到手头的问题。

最佳答案

可能是注入(inject)器决定存在循环引用。查看代码,我不会期望它,因为只有一个服务有构造函数。但是,您描述的行为指向了这一点。

您可以尝试注入(inject)注入(inject)器并延迟注入(inject)过程。
参见 Angular2: 2 services depending on each other

@Injectable()
export class CampaignService {
  static TYPE_CAMPAIGN = 'campaign';
  private entityService;

  constructor(injector: Injector) {
    setTimeout(() => this.entityService = injector.get(EntityService));
  }
}

在 campaign.service.ts 中使用 EntityService.TYPES

希望这涵盖了您的用例。 这是我的 StackBlitz

campaign.service.ts

import {Injectable, Injector} from '@angular/core';
import {EntityService} from './entity.service';

@Injectable()
export class CampaignService {
  static TYPE_CAMPAIGN = 'campaign';
  private entityService;
  types = EntityService.TYPES;

  constructor(private injector: Injector) {
    setTimeout( () => this.entityService = injector.get(EntityService) );
  }
}

app.component.ts

import { Component } from '@angular/core';
import {EntityService} from './entity.service';
import {CampaignService} from './campaign.service';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  types = EntityService.TYPES;

  constructor(
    private entityService: EntityService, 
    private campaignService: CampaignService
  ) { }
}

app.component.html

<hello name="{{ name }}"></hello>
<p>
  Start editing to see some magic happen :)
</p>
<div> Types from EntityService {{ types }} </div>
<div> Types from campaignService {{ campaignService.types }} </div>

关于angular - 服务相互包含时访问静态属性时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48123645/

相关文章:

javascript - 在 Angular2 上使用正则表达式制作管道

angular - 我无法将我的类(class)设置为 Ionic2 上的 promise

javascript - 使用 findIndex 检查对象数组中是否存在元素数组 - typescript

javascript - Redux,处理 Web API 调用的正确方法

angular - 如何为 Angular react 形式动态设置禁用?

angular - @h2qutc/angular-material-components 日期时间选择器和 SVG/第三方图标

javascript - 将模块导入 AngularJS 时出现 SystemJS 错误 - 匿名 System.register 调用只能由 SystemJS.import 加载的模块进行

mongodb - Mongoose 查询不显示子文档

inheritance - 在 TypeScript 中,一个接口(interface)可以扩展一个类,这是为了什么?

javascript - setTimeout() 函数的 TypeScript 装饰器