Angular 2 自定义服务未注入指令 [英] Angular 2 custom service not injected into a directive

查看:25
本文介绍了Angular 2 自定义服务未注入指令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这样的 app.component.

从angular2/core"导入{Component}从angular2/http"导入 {HTTP_PROVIDERS}从../service/chartData.service"导入 {ChartDataService}从../service/filter.service"导入 {FilterService}@成分({选择器:'应用',模板:`<sidebar (filterChange)="onFilterChange($event)"></sidebar><div dsChart></div>`,指令:[SidebarComponent, ChartDirective],提供者:[HTTP_PROVIDERS、FilterService、ChartDataService]、styleUrls: ['app/main/app.component.css']})导出类 AppComponent {//还有一些代码}

chartData.service.ts:

从 'angular2/core' 导入 {Injectable}从angular2/http"导入 {Http, Response, Headers, RequestOptions, RequestMethod}从 '../url' 导入 {Url}从'../model/filter.model' 导入 {FilterModel}从../model/node.model"导入{INode}@Injectable()导出类 ChartDataService {构造函数(私有_http:Http){this._headers.append('Content-Type', 'application/json');}获取数据(模型?:过滤模型){}}

然后我尝试在chart.directive中使用ChartDataService,它是app.component的子组件.chart.directive.ts:

import {Directive, ElementRef, Input, OnInit} from 'angular2/core'从../service/chartdata.service"导入 {ChartDataService}@指示({选择器:'[dsChart]'})导出类 ChartDirective 实现 OnInit {构造函数(私人 el: ElementRef,私人 _dataService: ChartDataService) {}ngOnInit() {this._dataService.getData().then(node => this._render(node)).catch(error => { 抛出错误});}私有 _render(root: INode) {}}

但是它通过文档失败了,每个组件都有一个注入器,它在组件级范围内创建依赖项.如果没有任何适当的组件级别提供程序,则使用父组件的提供程序.这适用于带有 @Component() 装饰器的类.将 providers: [ChartDataService] 添加到 @Directive 声明会有所帮助,但这意味着每个装饰器都会有单独的 ChartDataService 实例,这是不可取的.>

有什么想法吗?还是有意为之?

解决方案

这可能是导入顺序的问题...如果在 app.component.ts 中导入 ChartDirectiveChartDataService 之前,您可能会收到您提到的错误:

<块引用>

没有 ChartDataService 的提供者!(ChartDirective -> ChartDataService)

在导入组件本身之前,您应该导入子组件/指令使用的服务:

//没有错误从../service/chartData.service"导入 {ChartDataService}从 '../chart.directive' 导入 {ChartDirective}//可能导致错误从 '../chart.directive' 导入 {ChartDirective}从../service/chartData.service"导入 {ChartDataService}

我无法在此处重现此问题:

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?

解决方案

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 {...}

这篇关于Angular 2 自定义服务未注入指令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆