網站搜尋

typescript - Angular 沒有提供 NameService


我在將一個類加載到 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);

services/NameService.ts

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

我一直收到錯誤訊息,顯示 No provider for NameService。

有人可以幫我找出我程式碼的問題嗎?

答案#1

你必須使用 providers 而不是 injectables

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

完整的程式範例在這裡。

答案#2

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

  1. 啟動
  2. 根組件
  3. 其他元件或指令

「bootstrap 提供者選項旨在配置和覆寫 Angular 自己預先註冊的服務,例如其路由支持。」-- 參考

如果你只想在整個應用程式中擁有一個 NameService 的實例(即 Singleton),那麼將它包含在根組件的 providers 陣列中:

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

Plunker

如果你更希望每個元件有一個實例,請改為在元件的設定物件中使用 providers 陣列:

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

欲了解更多資訊,請參閱階層注入器文件。

答案#3

截至 Angular 2 Beta:

將 @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]
})

答案#4

你應該將 NameService 注入到你的 AppModule 的 NgModule 元資料中的 providers 陣列裡。

@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 元資料選項中。

答案#5

令人震驚的是,在最新版本的 Angular 中語法又再次改變了 :-) 來自 Angular 6 文檔:

從 Angular 6.0 開始,創建單例服務的首選方式是在服務上指定它應該在應用程序根中提供。這是通過在服務的 @Injectable 裝飾器上將 providedIn 設置為 root 來完成的:

src/app/user.service.0.ts

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

@Injectable({
  providedIn: 'root',
})
export class UserService {
}

答案#6

你應該在你的 AppModule 的 NgModule 元資料的 providers 陣列中注入 NameService。

@NgModule({
   providers: [MyService]
})

並且確保在你的組件中以相同名稱導入(區分大小寫),因為 SystemJs 天生區分大小寫。如果你在專案檔案中使用不同的路徑名稱,如下所示:

main.module.ts

import { MyService } from './MyService';

你的元件.ts

import { MyService } from './Myservice';

那麼 System js 將會進行雙重導入

答案#7

在 Angular v2 及以上版本現在是:

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