web-dev-qa-db-ja.com

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というエラーメッセージが表示され続けます。

誰かが私のコードで問題を見つけるのを手伝ってくれる?

271
M.Svrcek

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

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

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

406
Klas Mellbourn

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

  1. bootstrap
  2. ルートコンポーネント
  3. 他のコンポーネントまたはディレクティブ

「ブートストラッププロバイダオプションは、ルーティングのサポートなど、Angular独自の事前登録サービスを設定および上書きするためのものです。」 - 参照

アプリケーション全体でNameServiceのインスタンスを1つだけ(つまり、Singleton)にしたい場合は、ルートコンポーネントのproviders配列にそれを含めます。

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

Plunker

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

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

詳しくは 階層型インジェクタ のドキュメントをご覧ください。

73
Mark Rajcok

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]
})
33
magiccrafter

あなたはNameServiceprovidersメタデータのAppModule配列の中にNgModuleを注入するべきです。

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

}

アプリケーションの状態を気にせずに特定のコンポーネントレベルの依存関係を作成したい場合は、accept @Klass answerのようにコンポーネントのprovidersメタデータオプションへの依存関係を挿入できます。

20
Pankaj Parkar

あなたはあなたのAppModuleのNgModuleメタデータのprovider配列の中にNameServiceを注入するべきです。

@NgModule({
   providers: [MyService]
})

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

main.module.ts

import { MyService } from './MyService';

your-component.ts

import { MyService } from './Myservice';

その後System jsは二重インポートを行います

13
saghar.fadaei

Angular v2以降では、

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

12
supercobra

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を作成して、そしてそこでそれが最初に働くようにすることを勧めます。それはあなたのためにすべてを準備するでしょう。それがそこで働いていたら、あなたの他の環境にそれをコピーしてその環境に関する問題を切り分けます。

7
unobf

驚いたことに、構文は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 {
}
7
Derrick Miller

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

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

解決策:

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

次のようにbootstrap-commandで依存関係を宣言することもできます。

bootstrap(MyAppComponent,[NameService]);

少なくともそれがalpha40で私のために働いたものです。

これはリンクです: http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0

5
Tobias Gassmann

プロバイダーに追加します not injectables

@Component({
    selector:'my-app',
    providers: [NameService]
})
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> `   
    })
4
Shubham Verma

あなたはそれをプロバイダ配列に追加する必要があります。これはあなたのコンポーネントへのすべての依存を含みます。

角度付きドキュメンテーションのこのセクションを見てください。

コンポーネントにプロバイダを登録する

これが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と他のいくつかのものは消えています。

詳しくは here をご覧ください。

2
Alireza

app.module.tsファイルのprovider []配列にサービスを追加してください。以下のように

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

app.module.ts

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

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

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

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

効果:

  • すべてのコンポーネントに利用可能
  • 生涯利用可能

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

  • サービスはそのモジュールに宣言されたコンポーネントでのみ利用可能です

  • サービスは、モジュールがロードされている場合にのみ有効期間のアプリケーションで利用可能になります

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

効果:

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

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

  • 注入されたサービスのインスタンスは、コンポーネントとそのすべての子でのみ利用可能になります。

  • インスタンスはコンポーネントの有効期間中に使用可能になります。

1
Rzv Razvan

次のように@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
sachinkasana

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

bootstrap(MyAppComponent,[NameService]);
1
preet0982

ブロッククォート

コンポーネントにプロバイダーを登録する

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

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

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

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  `
})
export class HeroesComponent { }
0
ORBIT