Angular нет провайдера для NameService

у меня проблема с загрузкой класса в угловых компонент. Я пытаюсь решить долгое время, даже пытался добавить его в один файл. Вот что у меня есть:--3-->

приложение.ТС

/// <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.ТС

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

все время я получаю сообщение об ошибке "нет поставщика для NameService"...

может кто-нибудь помочь мне определить эту небольшую проблему с моим кодом?

16 ответов


вы должны использовать providers вместо injectables

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

полный образец кода здесь.


в Angular 2 есть три места, где вы можете "предоставить" услуги:

  1. загрузки
  2. корневой компонент
  3. другие компоненты или директивы

"параметр поставщика начальной загрузки предназначен для настройки и переопределения собственных предварительно зарегистрированных служб Angular, таких как поддержка маршрутизации."-- ссылка

если вы хотите только один экземпляр NameService во всем вашем приложении( т. е. Singleton), то включите его в providers массив корневой компонент:

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

Plunker

если вы предпочитаете иметь один экземпляр каждого из компонентов, использовать providers массив в объекте конфигурации компонента вместо:

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

посмотреть Иерархическая Форсунок DOC для получения дополнительной информации.


по состоянию на 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 as:

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

вы должны впрыскивать NameService внутри providers массив вашего AppModule ' s 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 {

}

если вы хотите создать зависимость для определенного уровня компонента, не беспокоясь о состоянии вашего приложения, то вы можете ввести эту зависимость от компонента providers метаданные, как принято @Klass ответ показал.


вы должны вводить NameService внутри массива поставщиков метаданных Ngmodule вашего AppModule.

@NgModule({
   providers: [MyService]
})

и убедитесь, что импорт в вашем компоненте с тем же именем (с учетом регистра),becouse SystemJs чувствителен к регистру (по дизайну). Если вы используете другое имя пути в своих файлах проекта, например:

main.модуль.ТС

import { MyService } from './MyService';

ваш компонент.ТС

import { MyService } from './Myservice';

тогда система js сделает двойной импорт


в Angular v2 и выше теперь:

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


угловой 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 и создать новый угловой 2 (ES6) plunk и заставить его работать там первым. Это все устроит для тебя. Как только он работает там, скопируйте его в другую среду и сортируйте любые проблемы с этим окружающая среда.


вы также можете иметь зависимости, объявленные в команде bootstrap, например:

bootstrap(MyAppComponent,[NameService]);

по крайней мере, это то, что сработало для меня в alpha40.

это ссылка:http://www.syntaxsuccess.com/viewarticle/dependency-injection-in-angular-2.0


ошибка No provider for NameService распространенная проблема, что многие Angular2 начинающих лицо.

причина: перед использованием любой пользовательской службы вы сначала должны зарегистрировать его в NgModule, добавив его в список поставщиков:

устранение:

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

привет , Вы можете использовать это в ваших .файл ТС :

импортировать ваши услуги .файл ТС:

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> `   
    })

добавить его в поставщики не инъекции

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

вам нужно добавить его в массив providers, который включает в себя все depency вашего компонента.

посмотрите на этот раздел в угловой документации:

Регистрация провайдеров в компоненте

вот пересмотренный Hereescomponent, который регистрирует HeroService в своем массив провайдеров.

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 должна быть доступна по всему приложения, поэтому он зарегистрирован в модуль @NgModule поставщиков матрица. Но поскольку HeroService используется только внутри героев feature area и нигде больше, имеет смысл зарегистрировать его в HeroesComponent.

см. Также "я должен добавить приложение-широкий поставщиков в корневой модуль или корневой AppComponent?"в FAQ по NgModule.

Так в вашем случае, просто измените injectables к провайдерам как ниже:

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

также в новых версиях Angular, @View и некоторых других материалов ушедший.

для получения дополнительной информации посетите здесь.


Angular2 требует, чтобы вы объявили все injectables в вызове функции начальной загрузки. Без этого ваш сервис не является инъекционным объектом.

bootstrap(MyAppComponent,[NameService]);

добавьте @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]
})

или если вы хотите получить доступ к своей службе по всему приложению, которое вы можете передать в App provider


добавьте свой сервис в массив providers[] в приложении.модуль.файл ТС. Как ниже

/ / здесь моя служба-CarService

app.модуль.ТС

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

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

шокирующе, синтаксис снова изменился в последней версии Angular : -) от угловой 6 docs:

начиная с Angular 6.0, предпочтительный способ создания синглтона услуги-указать на сервисе, что он должен быть предоставлен в корневой каталог приложения. Это делается путем установки providedIn в root on декоратор @Injectable обслуживания:

src / app / user.услуга.0.ТС

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

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