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

时间:2016-08-11 16:00:48

标签: javascript angular dependency-injection angular2-services

我有一个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 的服务,我按照上面的方式注入,它可以工作。

我在main.ts中引导ApiService

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 注入另一个组件时,它会给我错误, PagesService 没有提供商。 enter image description here

我像这样编写那个组件。

    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

频道组件是addPlaylist的父节点,addPlaylist是assignPlaylist的父节点。这种结构不起作用

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

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

我将提供者'PagesService'添加到ChannelComponent,还有AssignPlaylistComponent,它将起作用,没有错误。

即使这样也可以

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

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

1 个答案:

答案 0 :(得分:2)

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

如果组件指定了providers数组,组件树中的每个组件都将获得关联的“注入器”。我们可以把它想象成一个注入器树,它(通常很多)比组件树更稀疏。当需要解析依赖关系(通过组件或服务)时,将查询此注入器树。能够满足依赖性的第一个注入器就是这样做的。进样器树向上走,朝向根部件/进样器。

因此,为了让PagesService注入ApiService依赖项,首先必须使用注入器注册该ApiService对象。即,在组件的providers数组中。此注册必须发生在您要使用/注入ApiService的组件上或其上方。

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

另见Angular 2 - Including a provider in a service