NameService için açısal sağlayıcı yok


326

Açısal bir bileşene bir sınıf yüklerken sorun yaşıyorum. Uzun zamandır çözmeye çalışıyorum; Hatta hepsini tek bir dosyada birleştirmeyi denedim. Ne var:

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);

hizmet / NameService.ts

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

Diyerek bir hata mesajı alıyorum No provider for NameService.

Birisi kodumla ilgili sorunu tespit etmeme yardımcı olabilir mi?


6
Alpha 42'den itibaren: @Component ({sağlayıcılar: [NameService]})
timmz

Yanıtlar:


470

Sen kullanmak zorunda providersyerineinjectables

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

Kod örneğini burada tamamlayın .


7
@ unobf import ifadeleri bana kırık görünmüyor. Önceki yanıt, açısal2 kütüphanesinin eski alfaları için doğru olabilir. Orijinal kılavuz alfa-28, ben alfa 35 kullanın. Ayrıca, tam bir kod örneği için bir bağlantı sağlamak, bu yüzden oldukça fazla bilgi vermiş düşünüyorum.
Klas Mellbourn

4
Gelecekteki Google kullanıcıları için bir güncelleme: providersen son beta (beta 0) üzerinde çalışır.
nathanhleung

@nathanhleung hem ciltler hem de sağlayıcılar çalışır - bu geçici mi yoksa sadece dahili olarak aynı mı yapıyorlar
Simon_Weaver

@Simon_Weaver hmm son beta sürümünde değiştirmiş olabilirlerbindings
beta.0'da

1
hizmet başka bir hizmetten kullanılırsa ne olur? i küresel olarak kullanılabilir olacağını düşündüm modül sağlayıcılarına ekledi, ama yine de bu hatayı alıyorum
Sonic Soul

79

Açısal 2'de hizmet verebileceğiniz üç yer vardır:

  1. çizme atkısı
  2. kök bileşen
  3. diğer bileşenler veya direktifler

"Bootstrap sağlayıcısı seçeneği, Angular'ın yönlendirme desteği gibi önceden kaydedilmiş hizmetlerini yapılandırmak ve geçersiz kılmak için tasarlanmıştır." - referans

Tüm uygulamanızda (örneğin, Singleton) yalnızca bir NameService örneği istiyorsanız, bunu providerskök bileşeninizin dizisine ekleyin:

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

Plunker

Bileşen başına bir örneğiniz olmasını istiyorsanız providers, bileşenin yapılandırma nesnesindeki diziyi kullanın:

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

Daha fazla bilgi için Hiyerarşik Enjektörler belgesine bakın .


4
Bu gerçekten iyi bir cevap. Ayrıca, kök bileşende hizmet bildirimi ile diğer alt bileşenlerde bildirme arasındaki farkları da açıklar.
Taf

34

Açısal 2 Beta'dan itibaren:

Ekle @Injectableolarak hizmetinize:

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

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

    getNames() {
        return this.names;
    }
}

ve bileşen yapılandırmanıza aşağıdakini ekleyin providers:

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

22

Sen enjekte edilmelidir NameServiceiçeride providerssizin dizisi AppModule'ın NgModulemeta veri.

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

}

Uygulamanızın durumu hakkında endişelenmeden belirli bir bileşen düzeyi için bir Bağımlılık oluşturmak istiyorsanız, bu bağımlılığı gösterilen providerskabul edilen @Klass yanıtı gibi bileşen meta veri seçeneğine enjekte edebilirsiniz .


@NgModule bölümünde app.module.shared.ts'de bir hizmet eklemeyi denedim: sağlayıcılar: [DataManagerService] ama yine de hatayı alıyorum: Hata: DataManagerService için sağlayıcı yok!
Paul

1
@ Paul, hizmetinizi doğru Modül'e mi enjekte ediyorsunuz? ve yok DataManagerServicesahiptir @Injectableüzerine dekoratör?
Pankaj Parkar

15

Şaşırtıcı bir şekilde, sözdizimi Angular'ın son sürümünde tekrar değişti :-) Angular 6 dokümanlarından :

Açısal 6.0'dan başlayarak, tek bir hizmet oluşturmanın tercih edilen yolu, hizmetin uygulama kökünde sağlanması gerektiğini belirtmektir. Bu, hizmetin @Injectable dekoratörünün kök dizinine sağlananIn ayarı yapılarak yapılır:

src / uygulama / user.service.0.ts

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

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

14

AppModule'ün NgModule meta verilerinin sağlayıcılar dizisine NameService enjekte ediyor olmalısınız.

@NgModule({
   providers: [MyService]
})

ve SystemJ'lerin büyük / küçük harfe duyarlı olması nedeniyle (tasarım gereği) bileşeninize aynı ada (büyük / küçük harfe duyarlı) aktardığınızdan emin olun. Proje dosyalarınızda şu şekilde farklı bir yol adı kullanırsanız:

main.module.ts

import { MyService } from './MyService';

your-component.ts

import { MyService } from './Myservice';

System js çift ithalat yapacak


1
Mükemmel! İçe aktarımları gruplandırmak için varil kullanırken bu hatayla karşılaştım. SystemJS bahşişiniz bana yardımcı oldu :)
Jony Adamit

12

Açısal v2 ve üstü şimdi:

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


7

Açısal 2 değişti, kodunuzun üst kısmı şöyle görünmelidir:

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

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

Ayrıca hizmetinizde alıcıları ve ayarlayıcıları kullanmak isteyebilirsiniz:

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

Sonra uygulamanızda şunları yapabilirsiniz:

this.names = nameService.names;

Plnkr.co adresine gitmenizi ve yeni bir Angular 2 (ES6) gövdesi oluşturmanızı ve önce orada çalışmanızı öneririm. Sizin için her şeyi ayarlayacaktır. Orada çalıştıktan sonra diğer ortamınıza kopyalayın ve bu ortamla ilgili sorunları tetikleyin.


6

Hata No provider for NameService, birçok Angular2 yeni başlayanın karşılaştığı yaygın bir sorundur.

Sebep : Herhangi bir özel hizmeti kullanmadan önce, sağlayıcılar listesine ekleyerek NgModule'a kaydettirmeniz gerekir:

Çözüm:

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


4

Merhaba, Bunu .ts dosyanızda kullanabilirsiniz:

önce hizmetinizi bu .ts dosyasına aktarın:

import { Your_Service_Name } from './path_To_Your_Service_Name';

Sonra aynı dosyaya providers: [Your_Service_Name] :

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

4

Enjekte edilemeyen sağlayıcılara ekleyin

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

3

Angular'da bir hizmeti iki şekilde kaydedebilirsiniz:

1. Modül veya kök bileşende bir hizmet kaydedin

Etkileri:

  • Tüm bileşenlerde mevcuttur
  • Ömür boyu uygulamada mevcuttur

Tembel yüklü bir modüle servis kaydederken dikkatli olmalısınız:

  • Hizmet yalnızca bu modüle bildirilen bileşenlerde kullanılabilir

  • Hizmet yalnızca modül yüklendiğinde ömür boyu uygulamada kullanılabilir

2. Başka bir uygulama bileşenine hizmet kaydedin

Etkileri:

  • Bileşene Servisin ayrı bir örneği verilir

Başka bir uygulama bileşenine hizmet kaydederken dikkatli olmalısınız

  • Enjekte edilen servisin örneği yalnızca bileşene ve tüm çocuklarına sunulacaktır.

  • Örnek, bileşen ömrü boyunca kullanılabilir olacaktır.


2

Bileşeninizdeki tüm bağımlılıkları içeren sağlayıcılar dizisine eklemeniz gerekir.

Açısal belgelerdeki şu bölüme bakın:

Sağlayıcıları bir bileşene kaydetme

İşte HeroService'i sağlayıcılar dizisine kaydeden gözden geçirilmiş bir 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 ne zaman uygulama bileşenine karşı kullanılır?

Bir yandan, NgModule'deki bir sağlayıcı kök enjektöre kaydedilir. Bu, bir NgModule içinde kayıtlı her sağlayıcıya tüm uygulamadan erişilebileceği anlamına gelir.

Öte yandan, bir uygulama bileşenine kayıtlı bir sağlayıcı yalnızca bu bileşende ve tüm alt öğelerinde kullanılabilir.

Burada, APP_CONFIG hizmetinin uygulama genelinde kullanılabilir olması gerekir, bu nedenle AppModule @NgModule sağlayıcıları dizisine kaydedilir. Ancak HeroService yalnızca Heroes özellik alanında kullanıldığından ve başka hiçbir yerde kullanılmadığından, HeroesComponent'e kaydolmak mantıklıdır.

Ayrıca bkz. "Kök AppModule veya kök AppComponent'e uygulama genelinde sağlayıcılar eklemeli miyim?" NgModule SSS bölümünde bulabilirsiniz.

Yani sizin durumunuzda, enjektablları aşağıdaki gibi sağlayıcılara değiştirmeniz yeterlidir:

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

Ayrıca Angular'ın yeni sürümlerinde, @View ve diğer bazı şeyler gitti.

Daha fazla bilgi için burayı ziyaret edin .


2

hizmetinizi app.module.ts dosyasındaki sağlayıcılar [] dizisine ekleyin. Aşağıdaki gibi

// burada hizmetim CarService

app.module.ts

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

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

1

Angular2, bootstrap işlev çağrısındaki tüm enjektablları bildirmenizi gerektirir. Bu olmadan hizmetiniz enjekte edilebilir bir nesne değildir.

bootstrap(MyAppComponent,[NameService]);

1
Bu tam olarak doğru değil. Hizmeti bootstrap () öğesine veya providersbileşenin yapılandırma nesnesindeki diziye ekleyebiliriz . providersDiziye dahil edilirse , bağlı bileşen başına bir örnek alırız. Daha fazla bilgi için Hiyerarşik Enjektörler belgesine bakın .
Mark Rajcok

evet @MarkRajcok tarafından söylendiği gibi biz de tüm uygulama boyunca kullanmak zorunda olduğu bootstrap anda sadece bu hizmetleri sağlamak. böylece her bileşen için örnek oluşturacağından sağlayıcıya her seferinde enjekte etmemiz gerekmiyordu.
Pardeep Jain

1

@Injectable hizmetinize şu şekilde ekleyin:

export class NameService {
    names: Array<string>;

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

    getNames() {
        return this.names;
    }
}

ve bileşeninize sağlayıcıları şu şekilde ekleyin:

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

veya uygulamanın her yerinden hizmetinize erişmek istiyorsanız uygulama sağlayıcısına geçebilirsiniz


1

blockquote

Sağlayıcıları bir bileşene kaydetme

İşte HeroService'i sağlayıcılar dizisine kaydeden gözden geçirilmiş bir HeroesComponent.

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

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

@Component({
  selector: 'my-heroes',
  providers: [HeroService],
  template: `
  `
})
export class HeroesComponent { }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.