2015-06-01 44 views
197

我有加載類到Angular組件的問題。我試圖解決很長一段時間,甚至試圖將其添加到單個文件。我所擁有的是:Angular沒有名稱服務的提供者

Application.ts

/// <reference path="../typings/angular2/angular2.d.ts" /> 

import {Component,View,bootstrap,NgFor} from "angular2/angular2"; 
import {NameService} from "./services/NameService"; 

@Component({ 
    selector:'my-app', 
    injectables: [NameService] 
}) 
@View({ 
    template:'<h1>Hi {{name}}</h1>' + 
    '<p>Friends</p>' + 
    '<ul>' + 
    ' <li *ng-for="#name of names">{{name}}</li>' + 
    '</ul>', 
    directives:[NgFor] 
}) 

class MyAppComponent 
{ 
    name:string; 
    names:Array<string>; 

    constructor(nameService:NameService) 
    { 
     this.name = 'Michal'; 
     this.names = nameService.getNames(); 
    } 
} 
bootstrap(MyAppComponent); 

服務/ NameService.ts

export class NameService { 
    names: Array<string>; 
    constructor() { 
     this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"]; 
    } 
    getNames() 
    { 
     return this.names; 
    } 
} 

我收到錯誤消息說「不提供商名稱服務的所有時間「...

有人可以幫我發現我的代碼的小問題?

+4

阿爾法42: @Component({ 提供商:[名稱服務] } ) – mboullouz

回答

310

你必須使用providers代替injectables

@Component({ 
    selector: 'my-app', 
    providers: [NameService] 
}) 

Complete code sample here

+1

此答案不包括修復導入語句所需的更改。另外,你爲什麼不更新6月1日被接受的現有答案(當提問時)而不是創建一個部分的新答案? – unobf

+3

@unobf進口報表對我來說看起來並不難理解。以前的答案可能適用於angular2庫的舊alpha版本。原始指南是指alpha-28,我使用alpha 35。另外,我提供了一個完整代碼示例的鏈接,所以我認爲我提供了很多信息。 –

+2

未來googlers的更新:使用'providers'在最新beta版(測試版0)上運行。 – nathanhleung

6

角2變了,這裏是你的代碼的頂部應該是什麼樣子:

import { 
    ComponentAnnotation as Component, 
    ViewAnnotation as View, bootstrap 
} from 'angular2/angular2'; 
import {NameService} from "./services/NameService"; 

@Component({ 
    selector: 'app', 
    appInjector: [NameService] 
}) 

此外,您可能需要使用getter和setter方法在您的服務:

export class NameService { 
    _names: Array<string>; 
    constructor() { 
     this._names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"]; 
    } 
    get names() { 
     return this._names; 
    } 
} 

然後在您的應用程序,你可以簡單地做:

this.names = nameService.names; 

我建議你去plnkr.co並創建一個新的角度2(ES6)普及並讓它先在那裏工作。它會爲你設置一切。一旦它在那裏工作,將它複製到您的其他環境中,並利用該環境對任何問題進行分類。

1

Angular2要求你申報自舉功能調用的所有注射劑。沒有這個你的服務不是一個注射對象。

bootstrap(MyAppComponent,[NameService]); 
+1

這是不正確的。我們可以在bootstrap()中包含服務,或者在組件配置對象的'providers'數組中包含該服務。如果它包含在「提供者」數組中,則每個綁定組件將獲得一個實例。有關更多信息,請參閱[分層注入器](https://angular.io/docs/ts/latest/guide/hierarchical-dependency-injection.html)文檔。 –

+0

是的,就像@MarkRajcok所說的那樣,我們也只在引導時提供那些服務,我們必須在整個應用程序中使用這些服務。通過這樣做,我們不需要每次都注入提供程序,因爲它會爲每個組件創建實例。 –

54

在角2有三個地方可以 「提供」 服務:

  1. 引導
  2. 根組件
  3. 其他組件或指令

「的引導供應商選項用於配置和覆蓋Angular自己的預註冊服務,如路由支持。「 - reference

如果你只是想在您的整個應用程序(即,辛格爾頓)名稱服務的一個實例,則包括它的providers陣列的根組件在:

@Component({ 
    providers: [NameService], 
    ... 
)} 
export class AppComponent { ... } 

Plunker

如果您希望每個組件有一個實例,請在組件的配置對象中使用providers陣列:

@Component({ 
    providers: [NameService], 
    ... 
)} 
export class SomeOtherComponentOrDirective { ... } 

請參閱Hierarchical Injectors doc瞭解更多信息。

+1

這是一個非常好的答案。它進一步解釋了在根組件中聲明服務與在其他子組件中聲明的區別。 – Taf

26

由於角2測試版:

添加@Injectable到您的服務爲:

@Injectable() 
export class NameService { 
    names: Array<string>; 

    constructor() { 
     this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"]; 
    } 

    getNames() { 
     return this.names; 
    } 
} 

和您的組件配置添加providers爲:

@Component({ 
    selector: 'my-app', 
    providers: [NameService] 
}) 
7

在Angular v2現在是:

@Component({ selector:'my-app', providers: [NameService], template: ... })

17

你應該注射NameServiceproviders陣列您AppModuleNgModule元數據。

@NgModule({ 
    imports: [BrowserModule, ...], 
    declarations: [...], 
    bootstrap: [AppComponent], 
    //inject providers below if you want single instance to be share amongst app 
    providers: [MyService] 
}) 
export class AppModule { 

} 

如果不想打擾你的應用程序的狀態來創建特定的組件級的依賴,那麼你可以注入像顯示接受@Klass答案組件providers元數據選項依賴。

+0

我曾嘗試在@NgModule節中的app.module.shared.ts中添加一項服務:providers:[DataManagerService] 但仍然收到錯誤:錯誤:DataManagerService沒有提供程序! – Paul

+0

@Paul你是否注入了正確的模塊?並且'DataManagerService'上有'@ Injectable'裝飾器嗎? –

8

你應該在你的AppModule的NgModule元數據的providers數組中注入NameService。

@NgModule({ 
    providers: [MyService] 
}) 

並確保以相同的名稱導入組件(區分大小寫),因爲SystemJs區分大小寫(按設計)。如果您在項目文件中使用不同的路徑名如下:

main.module.ts

import { MyService } from './MyService'; 

您-component.ts

import { MyService } from './Myservice'; 

然後系統JS將雙進口

+0

非常好!當使用桶來分組時,我遇到了這個錯誤。你的SystemJS提示幫助了我:) –

3

嗨,你可以在你的.ts文件中使用它:

首先在此導入您的服務。TS文件:

import { Your_Service_Name } from './path_To_Your_Service_Name'; 

然後在同一個文件,你可以添加providers: [Your_Service_Name]

@Component({ 
     selector: 'my-app', 
     providers: [Your_Service_Name], 
     template: ` 
     <h1>Hello World</h1> ` 
    }) 
3

將它添加到提供商沒有注射

@Component({ 
    selector:'my-app', 
    providers: [NameService] 
}) 
3

無提供者名稱服務是Angular2開始的常見問題ER。

原因: 使用的自定義服務之前,我們必須先與NgModule在供應商列表中添加它來註冊它

解決方案:

@NgModule({ 
    imports: [...], 
    providers: [CustomServiceName] 
}) 
1

您需要將其添加到供應商陣列,其中包括所有對你的組件的依賴。

看這節角文檔中:

Registering providers in a component

Here's a revised HeroesComponent that registers the HeroService in its providers array.

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

import { HeroService } from './hero.service'; 

@Component({ 
    selector: 'my-heroes', 
    providers: [HeroService], 
    template: ` 
    <h2>Heroes</h2> 
    <hero-list></hero-list> 
    ` 
}) 
export class HeroesComponent { } 

When to use NgModule versus an application component

On the one hand, a provider in an NgModule is registered in the root injector. That means that every provider registered within an NgModule will be accessible in the entire application.

On the other hand, a provider registered in an application component is available only on that component and all its children.

Here, the APP_CONFIG service needs to be available all across the application, so it's registered in the AppModule @NgModule providers array. But since the HeroService is only used within the Heroes feature area and nowhere else, it makes sense to register it in the HeroesComponent.

Also see "Should I add app-wide providers to the root AppModule or the root AppComponent?" in the NgModule FAQ.

所以你的情況,簡單地改變注射到供應商,如下面:

@Component({ 
    selector: 'my-app', 
    providers: [NameService] 
}) 

而且在新版本Angular,@View和其他一些東西消失了。請致電here

0

添加@Injectable到您的服務爲:

export class NameService { 
    names: Array<string>; 

    constructor() { 
     this.names = ["Alice", "Aarav", "Martín", "Shannon", "Ariana", "Kai"]; 
    } 

    getNames() { 
     return this.names; 
    } 
} 

,並在您的組件添加提供商:

@Component({ 
    selector: 'my-app', 
    providers: [NameService] 
}) 

,或者如果你想在整個應用程序訪問您的服務,您可以通過在應用程序提供商

0

將您的服務添加到app.module.ts文件中的providers []數組。 像下面

//這裏我的服務是CarService

app.module.ts

import {CarsService} from './cars.service'; 

providers: [CarsService] // you can include as many services you have 
相關問題