【问题标题】:Angular Service Injection Issue: @Injectable Doesn't Work but Providers DoesAngular 服务注入问题:@Injectable 不起作用,但提供者可以
【发布时间】:2019-01-04 23:16:26
【问题描述】:

我浏览了 SO,但找不到任何与我看似奇怪的问题有关的内容。我将首先复制我的一些代码以提供上下文:

我的服务:

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

import { MyModule } from './my.module';

@Injectable({
  providedIn: MyModule,
})
export class ApiService {

  // router: Router;

  constructor() {
    // this.router = MyModule.injector.get(Router);
  }
... Some methods ...
}

我的模块:

import { NgModule, Injector } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { ConnectionsListComponent } from './connections-list/connections-list.component';
import { StoreModule } from '@ngrx/store';
import * as fromMy from './reducers';
import { routes } from './routes';
... component imports ...

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild(routes),
    StoreModule.forFeature('my', fromMy.reducers),
  ],
  declarations: [ConnectionsListComponent, MyShellComponentComponent, DashboardContainerComponent, DashboardElementComponent, DashboardElementInfoItemComponent],
  // providers: [ApiService]
})
export class MyModule {

  constructor() {

  }
}

我的组件:

import { Component, OnInit, Input } from '@angular/core';
import { AttributeArrayHelperService } from '../attribute-array-helper.service';
import { ApiService } from '../api.service';

.. some interfaces ...

@Component({
  selector: 'vz-dashboard-element',
  templateUrl: './dashboard-element.component.html',
  styleUrls: ['./dashboard-element.component.scss']
})
export class DashboardElementComponent implements OnInit {

  @Input() element: ElementInterface;
  @Input() erpType: String;

  equipmentAttributes: Object[] = []

  workOrderAttributes: Object[] = [

  ];

  constructor(private apiService: ApiService) {

   }

  ngOnInit() {
    const helper = new AttributeArrayHelperService();
    console.log(this.element);
    const lookupValues = helper.parseObjectArrayFor(this.element.Attributes, ['1', '2', '3']);
    console.log(lookupValues);
    const showValues = helper.parseArrayNames(lookupValues);
    console.log(showValues);
    console.log(this.apiService);
    console.log(this.apiService.getDashboardEntityInformation('4', '5', '6'));
    showValues.push();
    this.equipmentAttributes = showValues;
  }
}

好的,所以现在这是我的问题:当我尝试使用上面提到的 @Injectable 并声明了模块时,我在浏览器中收到以下错误,但没有 TS 编译错误(有虽然是一个循环参考警告):

DashboardContainerComponent.html:2 ERROR 错误: StaticInjectorError(AppModule)[DashboardElementComponent -> ApiService]:StaticInjectorError(平台: 核心)[DashboardElementComponent -> ApiService]: NullInjectorError:没有 ApiService 的提供者!

当我将其更改为使用 @Injectable() 并取消注释我的提供程序时,它似乎喜欢它并且一切都很好。我只是好奇这是为什么?从阅读 6.1 的 Angular 文档来看,这似乎符合需要。

有关更多信息,这一切都在一个子模块中,并且该服务旨在与该模块隔离。在这一点上,我只是对自己缺少什么感到困惑,作为我办公室中少数 JS 人员之一,也是唯一使用 Angular 的人,我没有第二双眼睛来帮助我识别我的东西'我不见了。

非常感谢这样做的任何帮助,因为这已经困扰我好几天了。提前致谢,

史蒂夫

编辑:要注意的另一件事是这是一个从 5 升级到 6 的应用程序。我按照指南进行操作,一切正常,所以也许它来自升级?

【问题讨论】:

  • 您是否尝试过重启应用,即重启ng serve
  • @AlfMoh 是的,我已经做过很多次了,而且每次重启后都会硬刷新浏览器。

标签: angular angular6


【解决方案1】:

所以在进一步研究了这个问题和功能之后,我发现我不是唯一一个遇到这个问题的人,这似乎来自对文档的误解。如此处所引用:GitHub Angular CLI Issue 10170 我的处理方式是错误的,尽管有关该功能的文档似乎会告诉您其他情况。

本质上,它正在创建一个导入循环,而 TS 正在努力防止此类问题的发生。现在推荐使用@Injectable() 的方法是使用{ providedIn: 'root' },这使得可注入服务在应用程序的根级别可用。话虽如此,如果它在多个模块或根模块中使用,它似乎只在顶层捆绑。如果该服务仅在单个子模块中使用,则它与该子模块捆绑在一起。

我的解决方案是改为

@Injectable({
  providedIn: 'root',
})

对于我的新服务,其余的我留在各自模块的模块定义的providers 数组中。至少在不再支持 providers 之前,这一切都会很好地协同工作,届时我会将它们全部转换为这种新格式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多