NameService에 대한 각도 없음 공급자


326

클래스를 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.

누군가 내 코드에서 문제를 발견하도록 도울 수 있습니까?


6
알파 42 현재 : @Component ({provider : [NameService]})
timmz

답변:


470

providers대신에 사용해야 합니다injectables

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

여기에서 코드 샘플을 완성하십시오 .


7
@unobf 가져 오기 문이 나에게 깨진 것처럼 보이지 않습니다. 이전 답변은 angular2 라이브러리의 오래된 알파에 적합 할 수 있습니다. 원래 가이드는 알파 -28을 참조하고 알파 35를 사용합니다. 또한 완전한 코드 샘플에 대한 링크를 제공하므로 많은 정보를 제공했다고 생각합니다.
Klas Mellbourn

4
향후 Google 직원을위한 업데이트 : providers최신 베타 (베타 0)에서 작동합니다.
nathanhleung

@nathanhleung 모두 바인딩 및 업체 작업 - 내부적으로 같은이 임시 또는 그들은 단지 일을
Simon_Weaver

@Simon_Weaver는 최신 베타 버전을 변경되었을 수 있습니다 HMM - beta.0에 내가 함께 작업에 가져올 수 없습니다bindings
nathanhleung

1
다른 서비스에서 서비스를 사용하면 어떻게됩니까? 전 세계에서 사용할 수있을 것으로 생각되는 모듈 제공 업체에 추가했지만 여전히 오류가 발생합니다.
Sonic Soul

79

Angular 2에는 서비스를 "제공"할 수있는 세 곳이 있습니다.

  1. 부트 스트랩
  2. 루트 컴포넌트
  3. 다른 구성 요소 또는 지침

"부트 스트랩 공급자 옵션은 라우팅 지원과 같은 Angular의 사전 등록 된 서비스를 구성하고 재정의하기위한 것입니다." - 참조

전체 앱 (예 : Singleton)에서 NameService 인스턴스를 하나만 원하는 경우 providers루트 구성 요소 의 배열에 포함하십시오.

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

Plunker

구성 요소 당 하나의 인스턴스를 원한다면 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안에 삽입해야합니다 .providersAppModuleNgModule

@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
@ 폴 당신은 올바른 모듈에 서비스를 주입하고 있습니까? 및 않습니다 DataManagerService가지고 @Injectable그 위에 장식을?
Pankaj Parkar

15

놀랍게도 구문은 최신 버전의 Angular에서 다시 변경되었습니다 :-) Angular 6 문서에서 :

Angular 6.0부터는 싱글 톤 서비스를 생성하는 기본 방법은 서비스에서 애플리케이션 루트에 제공해야하는 서비스를 지정하는 것입니다. 이는 서비스의 @Injectable 데코레이터에서 providedIn을 루트로 설정하여 수행됩니다.

src / app / user.service.0.ts

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

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

14

AppModule의 NgModule 메타 데이터의 공급자 배열에 NameService를 삽입해야합니다.

@NgModule({
   providers: [MyService]
})

SystemJ가 대소 문자를 구분하므로 설계 상 동일한 이름으로 대소 문자를 구분하여 구성 요소를 가져와야합니다. 프로젝트 파일에서 다음과 같이 다른 경로 이름을 사용하는 경우 :

main.module.ts

import { MyService } from './MyService';

your-component.ts

import { MyService } from './Myservice';

그런 다음 System js는 이중 가져 오기를 수행합니다.


1
우수한! 배럴을 사용하여 가져 오기를 그룹화 할 때이 오류가 발생했습니다. 귀하의 SystemJS 팁이 도움이되었습니다. :
Jony 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]
})

또한 서비스에서 getter 및 setter를 사용할 수 있습니다.

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에서는 다음 두 가지 방법으로 서비스를 등록 할 수 있습니다.

1. 모듈 또는 루트 구성 요소에 서비스 등록

효과 :

  • 모든 구성 요소에 사용 가능
  • 평생 적용 가능

지연로드 된 모듈에 서비스를 등록하는 경우주의해야합니다.

  • 서비스는 해당 모듈에 선언 된 구성 요소에서만 사용할 수 있습니다

  • 서비스는 모듈이로드 된 경우에만 평생 응용 프로그램에서 사용할 수 있습니다

2. 다른 응용 프로그램 구성 요소에 서비스 등록

효과 :

  • 구성 요소에 별도의 서비스 인스턴스가 주입됩니다.

다른 응용 프로그램 구성 요소에 서비스를 등록하는 경우주의해야합니다

  • 주입 된 서비스의 인스턴스는 구성 요소 및 모든 하위 요소에서만 사용할 수 있습니다.

  • 구성 요소 수명 동안 인스턴스를 사용할 수 있습니다.


2

구성 요소의 모든 종속성을 포함하는 providers 배열에 추가해야합니다.

각도 문서에서이 섹션을보십시오.

컴포넌트에 제공자 등록

다음은 공급자 배열에 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 파일의 provider [] 배열에 서비스를 추가하십시오. 아래처럼

// 여기 내 서비스는 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
이것은 정확하지 않습니다. 부트 스트랩 () 또는 providers구성 요소 구성 객체의 배열에 서비스를 포함시킬 수 있습니다 . providers배열에 포함 된 경우 바인딩 된 구성 요소 당 하나의 인스턴스를 얻습니다. 자세한 내용은 계층 적 인젝터 문서를 참조하십시오.
마크 Rajcok

@MarkRajcok이 말한 것처럼, 우리는 또한 부트 스트랩시 전체 서비스에서 사용해야하는 서비스 만 제공합니다. 이렇게하면 모든 구성 요소에 대한 인스턴스가 생성되므로 공급자에 매번 주입 할 필요가 없습니다.
Pardeep Jain

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.