Angular 2 custom service not injected into a directive

微笑、不失礼 提交于 2019-12-12 19:43:06

问题


I have app.component like this.

import {Component} from "angular2/core"
import {HTTP_PROVIDERS} from "angular2/http"

import {ChartDataService} from '../service/chartData.service'
import {FilterService} from "../service/filter.service"

@Component({
    selector: 'app',
    template: `
        <sidebar (filterChange)="onFilterChange($event)"></sidebar>
        <div dsChart></div>
    `,
    directives: [SidebarComponent, ChartDirective],
    providers: [HTTP_PROVIDERS, FilterService, ChartDataService],
    styleUrls: ['app/main/app.component.css']
})

export class AppComponent {
     //some more code
}

chartData.service.ts:

import {Injectable} from 'angular2/core'
import {Http, Response, Headers, RequestOptions, RequestMethod} from 'angular2/http'

import {Url} from '../url'
import {FilterModel} from '../model/filter.model'
import {INode} from "../model/node.model"

@Injectable()
export class ChartDataService {
    constructor(private _http: Http) {
        this._headers.append('Content-Type', 'application/json');
    }    

    getData(model?: FilterModel) {
    }
}

Then I try to use ChartDataService inside chart.directive, which is a child component to app.component. chart.directive.ts:

import {Directive, ElementRef, Input, OnInit} from 'angular2/core'
import {ChartDataService} from "../service/chartdata.service"

@Directive({
    selector: '[dsChart]'
})
export class ChartDirective implements OnInit {    
    constructor(
        private el: ElementRef,
        private _dataService: ChartDataService) {
    }

    ngOnInit() {
        this._dataService.getData()
            .then(node => this._render(node))
            .catch(error => { throw error });
    }

    private _render(root: INode) {}
}

But it fails with Via the docs each component has an injector which creates dependencies at a component level scope. If there are no any appropriate component level providers parent component's provider is used. This works fine for classes with @Component() decorator. Adding providers: [ChartDataService] to @Directive declaration helps, but that means each decorator will have separate instance of ChartDataService which is undesiarable.

Any ideas? Or is it by design?


回答1:


This could be an issue with order of imports... If in app.component.ts you import ChartDirective before ChartDataService you might get an error you mentioned:

No provider for ChartDataService! (ChartDirective -> ChartDataService)

You should import services that child components/directives use before importing component itself:

// no error
import {ChartDataService} from '../service/chartData.service'
import {ChartDirective} from '../chart.directive'

// can cause an error
import {ChartDirective} from '../chart.directive'
import {ChartDataService} from '../service/chartData.service'

I was unable to reproduce this issue here: http://plnkr.co/edit/NoZJnCMlqKkOMm5erfDW, but I can confirm it can happen:

// routes.ts
// no error
export {SettingsRoute} from './routes/settings/settings.route'
export {RootRoute} from './routes/root/root.route'

// this causes error
// export {RootRoute} from './routes/root/root.route'
// export {SettingsRoute} from './routes/settings/settings.route'

// root.route.ts
import {SettingsRoute} from './routes'
@RouteConfig([
  { path: '/settings/...', name: 'Settings', component: SettingsRoute },
])
export class RootRoute {...}




回答2:


I've forgotten to mention that I was using beta.7. After updating to beta.8 problem disappeared.



来源:https://stackoverflow.com/questions/35806636/angular-2-custom-service-not-injected-into-a-directive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!