angular2中没有服务错误的提供者,为什么我需要将它注入到它的父组件中?

No provider for service error in angular2, why do I need to inject it in it's parent component?

我有一个pages.service.ts

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

import { ApiService } from '../../apiService/api.service';

import { Playlists } from '../shared/playlists.model';


@Injectable()
export class PagesService {

  private currentPlaylists: Subject<Playlists> = new BehaviorSubject<Playlists>(new Playlists());

  constructor(private service: ApiService) {

  }


}

此页面服务需要另一个名为ApiService的服务,我按照上面的方式注入,有效。

我bootstrap ApiService 在main.ts

import { ApiService }  from './apiService/api.service';
import { AppComponent } from './app.component';

bootstrap(AppComponent,[
  disableDeprecatedForms(),
  provideForms(),
  HTTP_PROVIDERS,
  ROUTER_PROVIDERS,
  ApiService
]).catch((err: any) => console.error(err));;

但是当我尝试将 PagesService 注入另一个组件时,它给我错误, 没有提供者页面服务

那个组件我是这样写的

    import { Component, ViewChild, ElementRef, Input, Output, EventEmitter } from '@angular/core';
    import { CORE_DIRECTIVES } from '@angular/common';

    import { MODAL_DIRECTVES, BS_VIEW_PROVIDERS } from 'ng2-bootstrap/ng2-bootstrap';


    import { ApiService } from '../../apiService/api.service';
    import { PagesService } from '../../pages/shared/pages.service';


    @Component({
      selector: 'assign-playlist-modal',
      exportAs: 'assignModal',
      providers: [ PagesService ],
      directives: [MODAL_DIRECTVES, CORE_DIRECTIVES, FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES ],
      viewProviders: [BS_VIEW_PROVIDERS],
      styleUrls: ['app/channel/shared/assignPlaylist.css'],
      templateUrl: 'app/channel/modals/assignPlaylistModal.html'
    })

    export class AssignPlaylistModalComponent {


      constructor(private apiService: ApiService, private pageService: PagesService, fb: FormBuilder) {
       }
}

更新:这是我的文件结构

channel/
--channel.component.ts
--shared/
----assignPlaylist.modal.ts
----addPlaylist.modal.ts
pages/
--shared/
----pages.service.ts
--pages.component.ts

Channel组件是addPlaylist的父类,addPlaylist是assignPlaylist的父类。这个结构不行

ChannelComponent       
       |
AddPlaylistComponent
       |
AssignPlaylistComponent     ----PagesService----ApiService

我找到了一个解决方案,但不知道为什么我需要这样做,

我将提供程序 'PagesService' 添加到 ChannelComponent,还有 AssignPlaylistComponent,它会工作,没有错误。

即使这样也行得通

ChannelComponent            ----PagesService-------------
       |
AddPlaylistComponent
       |
AssignPlaylistComponent     ----ApiService---------------

但是,我只想在 AssignPlaylistComponent 中使用 PagesService,所以我认为在 channelcomponent.ts 中导入 PagesService 并在其中创建一个提供者数组是没有意义的。

有点奇怪,但是只有组件可以在Angular中配置依赖注入(嗯,还有bootstrap())。即,只有组件可以指定提供者。

如果组件指定了 providers 数组,则组件树中的每个组件都将获得关联的 "injector"。我们可以把它想象成一个注入器树,它(通常)比组件树稀疏。当需要解决依赖关系时(通过组件或服务),将查询此注入器树。可以满足依赖关系的第一个注入器会这样做。注入器树向上走,朝向根component/injector。

因此,为了让您的 PagesService 注入 ApiService 依赖项,该 ApiService 对象首先必须向注入器注册。即,在组件的 providers 数组中。此注册必须发生在您要 use/inject ApiService 的组件处或上方的某个位置。

您的服务随后应该能够注入已注册的 ApiService 对象,因为它会在注入器树中找到它。

另见