NameServiceのAngular No Provider


326

Angularコンポーネントにクラスをロードするときに問題が発生しました。私は長い間それを解決しようとしてきました。すべてを1つのファイルに結合することも試みました。私が持っているのは:

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

誰かが私のコードで問題を特定するのを手伝ってくれる?


6
Alpha 42以降:@Component({プロバイダー:[NameService]})
timmz '16年

回答:


470

providers代わりに使用する必要がありますinjectables

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

完全なコードサンプルはこちら


7
@unobfインポートステートメントが壊れているように見えません。以前の回答は、angular2ライブラリの古いアルファでは正しいかもしれません。元のガイドはalpha-28を参照していますが、alpha 35を使用しています。また、完全なコードサンプルへのリンクを提供しているので、かなり多くの情報を提供したと思います。
Klas Mellbourn、2015

4
今後のGoogle社員向けの更新:providers最新のベータ版(ベータ0)で動作します。
nathanhleung 2015

@nathanhleungバインディングとプロバイダーの両方が機能します-これは一時的なものですか、
それとも

@Simon_Weaverうーん、彼らは最新のベータ版でそれを変更した可能性があります-beta.0で私はそれを動作させることができませんでしたbindings
nathanhleung

1
サービスが別のサービスから使用されている場合はどうなりますか?私はそれをモジュールプロバイダーに追加しましたが、それをグローバルに利用できるようにするつもりですが、それでもエラーが発生します
Sonic Soul

79

Angular 2には、サービスを「提供」できる3つの場所があります:

  1. ブートストラップ
  2. ルートコンポーネント
  3. その他のコンポーネントまたはディレクティブ

「ブートストラッププロバイダーオプションは、ルーティングサポートなど、Angular自体の事前登録されたサービスを構成およびオーバーライドするためのものです。」- リファレンス

アプリ全体でNameServiceのインスタンスを1つだけ必要とする場合(つまり、シングルトン)、providersルートコンポーネントの配列にそれを含めます。

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

Plunker

コンポーネントごとに1つのインスタンスが必要な場合は、providers代わりにコンポーネントの設定オブジェクトの配列を使用します。

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

詳細については、階層型インジェクターのドキュメントをご覧ください。


4
これは本当に良い答えです。ルートコンポーネントでのサービスの宣言と他の子コンポーネントでの宣言の違いについても説明します。
Taf

34

Angular 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]
})

22

のメタデータの配列NameService内に注入する必要がprovidersあります。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 {

}

アプリケーションの状態を気にせずに特定のコンポーネントレベルの依存関係を作成する場合は、示されてprovidersいる承認された@Klass回答のように、コンポーネントのメタデータオプションに依存関係を注入できます。


@NgModuleセクションのapp.module.shared.tsにサービスを追加しようとしました:プロバイダー:[DataManagerService]でもエラーが発生します:エラー:DataManagerServiceのプロバイダーがありません!
Paul

1
@Paulは正しいモジュールにサービスを注入していますか?とんDataManagerServiceあり@Injectable、それ以上のデコレータを?
Pankaj Parkar 2017年

15

驚くべきことに、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 {
}

14

AppServiceのNgModuleメタデータのプロバイダー配列内にNameServiceを注入する必要があります。

@NgModule({
   providers: [MyService]
})

SystemJは大文字と小文字が区別されるため(設計上)、同じ名前(大文字と小文字を区別)でコンポーネントにインポートしてください。次のようにプロジェクトファイルで別のパス名を使用する場合:

main.module.ts

import { MyService } from './MyService';

your-component.ts

import { MyService } from './Myservice';

その後、システムjsは二重インポートを行います


1
優れた!バレルを使用してインポートをグループ化すると、このエラーが発生しました。あなたのSystemJS先端が助けてくれた:)
ジョニーズAdamit

12

Angular v2以降では、次のようになっています。

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


7

Angular 2が変更されました。コードの上部は次のようになります。

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

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

また、サービスでゲッターとセッターを使用することもできます。

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にアクセスして、新しいAngular 2(ES6)plunkを作成し、そこで動作させることをお勧めします。それはあなたのためにすべてを設定します。そこで動作するようになったら、それを他の環境にコピーして、その環境の問題を切り分けます。


6

このエラーNo provider for NameServiceは、多くのAngular2初心者が直面する一般的な問題です。

理由:カスタムサービスを使用する前に、プロバイダーリストに追加してNgModuleに登録する必要があります。

解決:

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


4

こんにちは、これを.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

Angularでは、2つの方法でサービスを登録できます:

1.モジュールまたはルートコンポーネントにサービスを登録します

効果:

  • すべてのコンポーネントで利用可能
  • 生涯アプリケーションで利用可能

遅延ロードされたモジュールにサービスを登録する場合は注意が必要です。

  • サービスは、そのモジュールに宣言されたコンポーネントでのみ使用できます

  • サービスは、モジュールがロードされている場合にのみ、ライフタイムアプリケーションで利用できます

2.他のアプリケーションコンポーネントにサービスを登録する

効果:

  • サービスの個別のインスタンスがコンポーネントに注入されます

他のアプリケーションコンポーネントにサービスを登録する場合は注意が必要です

  • 挿入されたサービスのインスタンスは、コンポーネントとそのすべての子でのみ使用できます。

  • インスタンスはコンポーネントのライフタイムで利用できます。


2

コンポーネントのすべての依存関係を含むプロバイダー配列にそれを追加する必要があります。

角度のドキュメントでこのセクションを見てください:

コンポーネントへのプロバイダーの登録

以下は、プロバイダー配列にHeroServiceを登録する改訂されたHeroesComponentです。

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

NgModuleとアプリケーションコンポーネントを使用する場合

一方、NgModuleのプロバイダーはルートインジェクターに登録されます。つまり、NgModule内に登録されているすべてのプロバイダーは、アプリケーション全体でアクセスできます。

一方、アプリケーションコンポーネントに登録されたプロバイダーは、そのコンポーネントとそのすべての子でのみ使用できます。

ここで、APP_CONFIGサービスはアプリケーション全体で使用できる必要があるため、AppModule @NgModuleプロバイダー配列に登録されます。ただし、HeroServiceはHeroes機能領域内でのみ使用され、他の場所では使用されないため、HeroesComponentに登録することは理にかなっています。

「アプリ全体のプロバイダーをルートAppModuleまたはルートAppComponentに追加する必要がありますか?」も参照してください。NgModule FAQにあります。

したがって、あなたのケースでは、単に次のようなプロバイダーに注射を変更します:

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

また、Angularの新しいバージョンでは、@ Viewや他のいくつかのものがなくなりました。

詳細については、こちらをご覧ください


2

app.module.tsファイルのプロバイダー[]配列にサービスを追加します。以下のように

//ここでのサービスはCarServiceです

app.module.ts

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

providers: [CarsService] // you can include as many services you have 

1

Angular2では、ブートストラップ関数呼び出しですべてのインジェクタブルを宣言する必要があります。これがなければ、サービスは注入可能なオブジェクトではありません。

bootstrap(MyAppComponent,[NameService]);

1
これは正しくありません。サービスをbootstrap()に含めるかproviders、コンポーネントの構成オブジェクトの配列に含めることができます。providers配列に含まれている場合、バインドされたコンポーネントごとに1つのインスタンスを取得します。詳細については、階層型インジェクターのドキュメントをご覧ください。
Mark Rajcok、2015年

はい、@ MarkRajcokによると、アプリ全体で使用する必要のあるサービスのみをブートストラップ時に提供します。そうすることで、すべてのコンポーネントのインスタンスを作成するため、プロバイダーに毎回注入する必要がなくなりました。
Pardeep Jain、2016

1

次のように@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]
})

または、アプリケーション全体でサービスにアクセスする場合は、アプリプロバイダーに渡すことができます


1

ブロッククォート

コンポーネントへのプロバイダーの登録

以下は、プロバイダー配列にHeroServiceを登録する改訂されたHeroesComponentです。

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

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

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  `
})
export class HeroesComponent { }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.