예외 : 모든 매개 변수를 해석 할 수 없습니다


431

Angular 2에서 기본 앱을 만들었지 만 구성 요소 중 하나에 서비스를 주입 할 수없는 이상한 문제가 발생했습니다. 그러나 내가 만든 세 가지 다른 구성 요소 중 하나에 미세하게 주입합니다.

우선, 이것은 서비스입니다 :

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

@Injectable()
export class MobileService {
  screenWidth: number;
  screenHeight: number;

  constructor() {
    this.screenWidth = window.outerWidth;
    this.screenHeight = window.outerHeight;

    window.addEventListener("resize", this.onWindowResize.bind(this) )
  }

  onWindowResize(ev: Event) {
    var win = (ev.currentTarget as Window);
    this.screenWidth = win.outerWidth;
    this.screenHeight = win.outerHeight;
  }

}

그리고 작업을 거부하는 구성 요소 :

import { Component, } from '@angular/core';
import { NgClass } from '@angular/common';
import { ROUTER_DIRECTIVES } from '@angular/router';

import {MobileService} from '../';

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
})
export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(public ms: MobileService) {
    console.log(ms);
  }

}

브라우저 콘솔에서 발생하는 오류는 다음과 같습니다.

예외 : HeaderComponent :(?)의 모든 매개 변수를 확인할 수 없습니다.

부트 스트랩 기능에 서비스가 있으므로 공급자가 있습니다. 그리고 나는 그것을 문제없이 다른 구성 요소의 생성자에 주입 할 수있는 것 같습니다.


14
아마도 수입? 가 (배럴)? 대신 직접 선언 된 파일에서 가져 오려고 시도 할 수 있습니까? '../'index.ts
Günter Zöchbauer 2016 년

기적적으로 그것은 그것을 고친 것 같습니다! 내가 서비스를 테스트 한 다른 구성 요소가 배럴을 사용하면 작동하지 않을 것입니다. 의견 대신 답변으로 게시하려면 동의합니다.
Keith Otto

11
일반적으로 순환 종속성.
Gary

순환 종속성과 관련 하여이 문제가 발생했습니다. 이 알려주에서 웹 팩의 최신 버전이 훨씬 더 나은 것을주의 그것의 가치
Enn은

원형 종속성처럼 보입니다 .angular> = 4를 사용하면 intex.ts (배럴)를 제거하고 필요한 모든 것을 직접 가져올 수 있습니다.
Rammgarot

답변:


457

배럴 대신 직접 선언 된 파일에서 가져옵니다.

정확히 문제의 원인을 모르겠지만 여러 번 언급했을 것입니다 (아마도 일종의 순환 종속성).

또한 배럴의 수출 순서를 변경하여 해결할 수 있어야합니다 (세부 사항은 모르지만 언급되었습니다)


16
예를 들어 배럴에서 첫 번째 서비스를 먼저 가져와야하는 다른 서비스에 서비스를 주입 한 경우 이는 올바른 것입니다.
Joao Garin

17
Angular2 팀은 그러한 문제로 인해 더 이상 배럴을 권장하지 않습니다. 내가 :) 도움이 될 수 다행
귄터 Zöchbauer

13
Angular 2 팀이 배럴을 권장하지 않는다는 것을 몰랐습니다. 그렇다면 용어집 에서 이점을 설명하는 점에 유의해야합니다 . 그리고 angular2-webpack-starter 와 같은 프로젝트 는 사용해서는 안됩니다.
Blue

3
이 문제가 해결되었습니다 (에서 문제가되지 않음 2.0.2). 다른 모듈간에 여러 모델과 서비스를 가져와야 할 때 배럴이 여전히 유용하다는 것을 알았습니다. 이것은 import { cleanValues, getState, FirebaseService, NotificationService, ... } from '../../shared/services';이 작품 (안했을 때 고통이었다 NgModule싱글 서비스에 더 도움이 ... 없습니다
Sasxa

3
Argghh 나는 배럴 (index.ts) 파일의 내보내기 순서를 변경하여 문제를 해결했습니다. 정말 감사합니다
Spock

331

주어진 이전 답변 외에도 주사 가능한 서비스에 실제 @Injectable()데코레이터 가 없으면이 오류가 발생하는 것 같습니다 . 따라서 주기적 종속성 항목과 가져 오기 / 내보내기 순서를 디버그하기 전에 서비스가 실제로 @Injectable()정의되어 있는지 간단한 확인을 수행하십시오 .

이것은 현재 Angular 최신 인 Angular 2.1.0에 적용됩니다.

나는이 문제에 관한 이슈를 열었다 .


예,이 오류는 일반적으로 @Injectable을 추가하는 것을 잊어 버렸기 때문에 발생합니다. 예를 들어 Router'@ angular / router'를 가져 오는 중일 수 있으며이 인젝터 블 이 없으면이 오류는 항상 발생합니다 ( 주입 된 라우터의 코드 사용
Eric Bishard

놀랍게도 내 문제는 서비스에 메소드를 추가하고 마지막 괄호 뒤에 세미 콜론을 추가하지 않았다는 것입니다. 나는 이것이 왜 이런 식이어야하는지 전혀 모른다. 그러나 컴포넌트 클래스에서는 그렇지 않다 ... 지금은 계속해서 기쁘다!
egimaben

나는이 오류를 낸 간단한 모델을 가지고있었습니다. 모델 생성자에서 속성을 만드는 바로 가기를 사용했습니다. 속성의 유형은 문자열과 int입니다. 그런 다음 갑자기이 문제가 발생하기 시작했습니다. @Injectable ()을 추가하면 문제가 해결되었습니다. 다른 모델에 Injectable을 추가하지 않았기 때문에 이상합니다. 이 새 모델을 추가하기 전에 상당히 많은 라이브러리를 업그레이드했음을 추가해야합니다. 아마도 그것과 관련이 있었지만 지금 일하고 있습니다. 감사.
Moutono

@Moutono 맞습니다. 서비스에 빈 생성자가 있으면 종속성 주입이 트리거 @injectable()되지 않고 필요하지 않습니다. 또 다른 이상한 점이 있습니다. 좋은 측정을 위해, 나는 당신이 무언가를 주입하기로 결정할 때를 위해 여전히 그것을 추가 할 것입니다.
JP ten Berge

서비스에 @Injectable ()으로 장식해야하는 기본 클래스가있는 경우
Sam Shiles

110

Angular 2.2.3에는 forwardRef()아직 정의되지 않은 공급자를 주입 할 수 있는 유틸리티 기능이 있습니다.

정의되지 않았으므로 종속성 주입 맵이 식별자를 알지 못합니다. 이것은 순환 종속성 동안 발생합니다. Angular에서 원형 의존성으로 인해 풀거나보기가 매우 어렵습니다.

export class HeaderComponent {
  mobileNav: boolean = false;

  constructor(@Inject(forwardRef(() => MobileService)) public ms: MobileService) {
    console.log(ms);
  }

}

@Inject(forwardRef(() => MobileService))원래 질문의 소스 코드에서 생성자의 매개 변수에 추가 하면 문제가 해결됩니다.

참고 문헌

각도 2 매뉴얼 : ForwardRef

Angular 2의 참조 참조


3
forwardRef()이미 알파에 있었지만 ;-) Mobile서비스가 동일한 파일에서 더 아래로 선언 된 경우에만 필요 합니다. 클래스가 다른 파일에있는 경우에 대한 필요가 없습니다forwardRef()
귄터 Zöchbauer

4
Günter Zöchbauer, 나는 여전히 내 코드의 실제 문제를 파악하려고 노력하고 있지만 그 동안 메시지를 forwardRef()제거하는 데 도움이되었습니다 Can't resolve all parameters for .... 문제에 대한 더 나은 해결책을 찾고있는 동안 적어도 구성 요소가 작동하고 있습니다. (그렇습니다. 실패한 종속성은 파일에서 직접 가져옵니다)
Nik

4
@ GünterZöchbauer 참고로 답변을 업데이트했습니다. 나는 당신의 대답에서 벗어나려고하지 않지만 실제로 이것은 문제를 해결하고 사람들은 그것에 대해 알아야합니다. Google에 질문이 있으면을 (를) 사용하는 결과가 없습니다 forwardRef. 찾기가 매우 어렵습니다. 어제 하루 종일이 문제를 해결했습니다.
Reactgular

기묘한. 나는 foreardRef나 자신을 사용하도록 제안 하지만 더 이상 NgModule소개 되지 않은 제안을 적어도 12 가지 게시했습니다 . 담당자를 잃어 버릴 염려가 없습니다. 몇 달 후에 더 이상 팝업이 표시되지 않는 이유가 무엇인지 궁금합니다. 며칠 만에 집에 돌아 오면 자세히 살펴볼 것입니다. 의견을 보내 주셔서 감사합니다.
Günter Zöchbauer

2
수입품에 대해 누군가 분실 한 경우 : import {Component, Inject, ForwardRefFn, forwardRef} from '@ angular / core';
Natanael

69

잘못된 # 1 : 잊어 버린 데코레이터 :

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
export class MyFooService { ... }

잘못된 # 2 : "@"기호 생략

//Uncaught Error: Can't resolve all parameters for MyFooService: (?).
Injectable()
export class MyFooService { ... }

잘못된 # 3 : "()"기호 생략

//Uncaught Error: Can't resolve all parameters for TypeDecorator: (?).
@Injectable
export class MyFooService { ... }

잘못된 # 4 : 소문자 "i":

//Uncaught ReferenceError: injectable is not defined
@injectable
export class MyFooService { ... }

잘못된 # 5 : 당신은 잊었다 : import {Injectable} from '@ angular / core';

//Uncaught ReferenceError: Injectable is not defined
@Injectable
export class MyFooService { ... }

옳은:

@Injectable()
export class MyFooService { ... }


21

또한 서비스 A를 서비스 B에 주입하고 그 반대도 마찬가지입니다.

어쨌든 피해야하기 때문에 이것이 빨리 실패하는 것이 좋은 것이라고 생각합니다 . 서비스를보다 모듈화하고 재사용 할 수있게하려면 순환 참조를 최대한 피하는 것이 가장 좋습니다. 이 게시물 은 그 주변의 함정을 강조합니다.

따라서 다음 권장 사항이 있습니다.

  • 당신은 클래스가 너무 자주 (I 이야기하고 상호 작용 느끼면 기능 선망 ), 당신이 고려하는 것이 좋습니다 1 개 클래스로이 개 서비스를 병합 .
  • 위의 방법으로 문제가 해결되지 않으면 메시지를 교환하기 위해 두 서비스 모두에 삽입 할 수 있는 3 번째 서비스 ( EventService)를 사용해보십시오 .

1
이것은 분명히 나에게 일어난 일이며, 이것이 갈 길입니다. 업데이트가 필요한 서비스가 두 개 이상인 경우 EventService를 사용하십시오. 이러한 이벤트를 기반으로 응용 프로그램을 확장 할 때 해당 이벤트를 활용해야한다는 점에서 확장 성이 뛰어납니다.
themightybun

17

검색 자의 이익을 위해; 이 오류가 발생했습니다. 단순히 누락 된 @ 기호였습니다.

Can't resolve all parameters for MyHttpService오류가 발생합니다.

Injectable()
export class MyHttpService{
}

누락 된 @기호를 추가하면 문제가 해결됩니다.

@Injectable()
export class MyHttpService{
}

2
필자의 경우 @Injectable과 서비스 클래스 정의 사이에 추가 클래스와 인터페이스를 추가하여 서비스 클래스가 더 이상 주입 가능으로 표시되지 않았습니다.
Herc

다른 인젝터 블 서비스를 사용하는 서비스 클래스에서 @Injectable () 데코레이터를 완전히 잊어 버린 경우 잘못 장식 된 서비스에서도이 오류가 발생합니다.
I. Buchan

10

제 경우에는 작업을 수행 import "core-js/es7/reflect";하기 위해 응용 프로그램에 추가 해야 @Injectable했습니다.


9

emitDecoratorMetadatatsconfig.json에서 다른 가능성이 true로 설정 되지 않았습니다.

{
  "compilerOptions": {

     ...

    "emitDecoratorMetadata": true,

     ...

    }

}

8

당신이 서비스가있는 경우이 오류가 에 따라 정적 속성 / 메소드 서비스의 B 와 서비스 B 자체가 서비스에 따라 달라집니다 트로프 의존성 주입을. 따라서 속성 / 메서드가 정적이 아니기 때문에 일종의 순환 종속성입니다. AOT 와 함께 발생하는 버그 일 수 있습니다.


또한 동일한 파일에 단순히 정의 된 함수에 대한 종속성이있을 때도 사용했습니다. 그것을 별도의 파일로 나누면 문제가 해결되었습니다.
Joe

1
언급 해 주셔서 감사합니다. 나는 정확한 상황에서 나 자신을 발견했다. 정적 클래스에 직접 액세스하면 DI와 관련이 있다는 것을 알지 못했습니다. 나는이 구성표를 가지고 있었고 A -> B둘 다 동일한 정적 클래스를 사용하고있었습니다. forwardRef도움 이되는 해결책 이지만 이것이 어떻게 풀릴 수 있는지 살펴 보겠습니다. 아마도이 정적 클래스에서 실제 서비스를 시도 할 것입니다 (더 나은 디자인으로 이어질 것입니다).
Slava Fomin II

8

누락 된 @Injectable()데코레이터 외에도

@Injectable()추상 클래스에 누락 된 데코레이터가 서비스에 대한 모든 매개 변수를 해석 할 수 없음을 생성 함 : (?) 데코레이터 MyService는 파생 클래스뿐만 아니라BaseService

//abstract class
@Injectable()
abstract class BaseService { ... }

//MyService    
@Injectable()
export class MyService extends BaseService {
.....
}

7

필자의 경우 생성자 매개 변수의 유형을 선언하지 않았기 때문에 발생했습니다.

나는 이런 식으로했다 :

constructor(private URL, private http: Http) { }

그런 다음 아래 코드로 변경하면 문제가 해결되었습니다.

constructor(private URL : string, private http: Http) {}

5

나를 위해 그것은 ()@Injectable에 부족 했습니다. 적절한 @Injectable ()입니다


또는 제 경우에는 실수로 @
TDP를

4

injectable constructor () 메소드에서 매개 변수를 제거하면 필자의 경우 해결되었습니다.


이것은 또한 내 문제였습니다. 나는 그것을 게시하기 위해 왔지만 당신이 먼저 한 것을 발견했습니다! +1
aesede

그런 다음 재사용 가능한 서비스에 매개 변수를 보내는 방법은 무엇입니까?
3g 웹 트레인


2

글쎄, 문제는 훨씬 성가신 것이었다. 서비스 내에서 서비스를 사용하고 appModule에 의존성으로 추가하는 것을 잊었다! 희망은 누군가가 몇 시간 동안 앱을 다시 빌드하기 위해 앱을 분해하는 데 도움이되기를 바랍니다.


1
방금 @Inject주석이 누락되었습니다 . 오류 메시지의 내용을 정확히 간과했습니다. 순환 종속성이 의심되지 않으면 오류에 언급 된 클래스로 이동하여 모든 생성자 매개 변수와 주석이 달린 모든 클래스 멤버를보고 @InjectDI에서 올바르게 수행하고 있는지 확인하십시오. DI에 대한 자세한 내용은 여기 : angular.io/docs/ts/latest/guide/dependency-injection.html
Alexander Taylor

2

@Component 데코레이터 또는 컴포넌트가 선언 된 모듈에 제공자 배열을 추가해야합니다. 내부 구성 요소는 다음과 같이 수행 할 수 있습니다.

@Component({
  moduleId: module.id,
  selector: 'pm-header',
  templateUrl: 'header.component.html',
  styleUrls: ['header.component.css'],
  directives: [ROUTER_DIRECTIVES, NgClass],
  providers: [MobileService]
})

2

필자의 경우 잘못된 매개 변수를 생성자에 전달하면이 오류가 발생하지만이 오류에 대한 기본 아이디어는 실수로 일부 잘못된 인수를 함수에 전달한다는 것입니다.

export class ProductComponent {
    productList: Array<Product>;

    constructor(productList:Product) { 
         // productList:Product this arg was causing error of unresolved parameters.
         this.productList = [];
    }
}

나는 그 주장을 제거함으로써 이것을 해결했습니다.


2

나를 위해 polyfills.ts 파일 에서이 가져 오기를 실수로 비활성화 했을 때이 오류 가 발생했습니다. 오류를 피하려면 가져 오기를 확인해야합니다.

/** Evergreen browsers require these. **/
// Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
import 'core-js/es7/reflect';

2

내 경우에는 NativeDateAdapter" format(date: Date, displayFormat: Object)"메서드 를 재정의하기 위해 " " 확장하려고했습니다 .

AngularMaterial-2 DatePicker에서.

그래서 기본적으로 @Injectable주석 을 추가하는 것을 잊었습니다 .

이것을 "CustomDateAdapter"클래스에 추가 한 후 :

@Injectable({
  providedIn: 'root'
})

오류가 발생했습니다.


이것은 나를 위해 일했지만 왜 그런지 모르겠습니다. DI가 작동하려면 서비스를 통해 DI를 통해 서비스와 서비스를받는 구성 요소를 모두 제공해야합니까?
Mike Furlender

2

이 답변 은이 문제에 매우 도움이 될 수 있습니다. 또한 필자의 경우 서비스를 내보내기 default로했습니다.

잘못된:

@Inject()
export default class MobileService { ... }

옳은:

@Inject()
export class MobileService { ... }

2

오류 피드백이 없기 때문에 디버그하기가 매우 어려울 수 있습니다. 실제 순환 종속성에 대해 우려하는 경우 스택 추적에서 가장 중요한 사항은 a) 서비스 이름 b) 물음표가있는 해당 서비스의 생성자 매개 변수입니다. 예를 들면 다음과 같습니다.

AuthService의 모든 매개 변수를 분석 할 수 없습니다 : ([object Object], [object Object], [object Object], [object Object],?)

이는 5 번째 매개 변수가 AuthService에 의존하는 서비스임을 의미합니다. 즉 물음표는 DI로 해결되지 않았 음을 의미합니다.

여기에서 코드를 재구성하여 두 서비스를 분리하면됩니다.


1

서비스 이름, 즉 생성자 (private myService : MyService )를 잘못 입력 하여이 오류가 발생했습니다 .

철자가 틀린 서비스의 경우 Chrome-> Console에서 페이지를 검사하여 어떤 서비스가 문제 (생성자에 여러 개 나열되어 있음)가 있는지 확인할 수있었습니다. 메시지의 일부로 object Object, object Object,?를 표시하여 "매개 변수"배열 목록을 볼 수 있습니다. (또는 그런 것). 어디에 "?" 는 문제의 원인이되는 서비스의 위치입니다.


1

배럴 내에서 내 보낸 클래스 의 순서 가 언급되었지만 다음 시나리오에서도 동일한 효과가 발생할 수 있습니다.

당신이 수업을 가정 A, B그리고 C같은 파일 내에서 수출 A에 의존 B하고 C:

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

@Injectable()
export class B {...}

@Injectable()
export class C {...}

이후 에 의존 (이 경우 클래스에서 즉, 클래스 B와는 C) 아직 (각도에 알 수없는 클래스 각도의 의존성 주입 과정에서 아마 실행시A ) 오류가 발생합니다.

해결책

해결책은 DI가 수행되는 클래스보다 종속 클래스를 선언하고 내보내는 것입니다.

즉, 위의 경우 클래스 A는 종속성이 정의 된 직후 선언됩니다.

@Injectable()
export class B {...}

@Injectable()
export class C {...}

@Injectable()
export class A {
    /** dependencies injected */
    constructor(private b: B, private c: C) {}
}

1

필자의 경우 동일한 구성 요소 파일에서 클래스와 Enum을 내보내고있었습니다.

mComponent.component.ts:

export class MyComponentClass{...}
export enum MyEnum{...}

그런 다음 MyEnum의 아이에게서 사용하려고했습니다 MyComponentClass. 이로 인해 모든 매개 변수를 해결할 수 없음 오류가 발생했습니다 .

MyEnum에서 별도의 폴더 로 이동 하면 MyComponentClass문제가 해결되었습니다.

Günter Zöchbauer가 언급했듯이 이는 서비스 또는 구성 요소가 순환 적으로 종속되기 때문에 발생합니다.


1

서비스가 컴포넌트와 동일한 파일에 정의되어 있고 (소비하는) 서비스가 파일의 컴포넌트 뒤에 정의 된 경우이 오류가 발생할 수 있습니다. 이는 다른 사람들이 언급 한 것과 동일한 'forwardRef'문제 때문입니다. 현재 VSCode는이 오류를 표시하지 않으며 빌드가 성공적으로 컴파일됩니다.

로 빌드를 실행하면 --aot컴파일러 작동 방식 (아마 트리 흔들림과 관련됨)으로 인해이 문제를 숨길 수 있습니다.

솔루션 : 서비스가 다른 파일 또는 구성 요소 정의 전에 정의되어 있는지 확인하십시오. (이 경우 forwardRef를 사용할 수 있는지 확실하지 않지만 그렇게하는 것은 서투른 것 같습니다).

구성 요소 (보기 모델과 같은 종류)와 매우 밀접한 관련이있는 매우 간단한 서비스가 있다면-예를 들어. ImageCarouselComponent, ImageCarouselComponent.service.ts다른 서비스와 혼동되지 않도록 이름을 지정할 수 있습니다.


1

내 경우에는 순환 참조였습니다. MyService에 Myservice2를 호출하고 MyService2에 MyService를 호출했습니다.

안좋다 :(


1

제 경우에는 그 이유는 다음과 같습니다.

  • 주사 가능한 서비스 A 다른 클래스 B 확장
  • B에는 인수가 필요한 생성자가 있습니다.
  • A에서 생성자를 정의하지 않았습니다.

결과적으로 객체 A를 만들려고 할 때 기본 생성자가 실패했습니다. 이것이 왜 컴파일 오류가 아닌지 전혀 모른다.

A의 생성자를 추가하여 고정했습니다 .B의 생성자를 올바르게 호출했습니다.


1

잡았다!

위의 답변 중 어느 것도 도움이되지 않으면 구성 요소가 서비스를 주입하는 동일한 파일 에서 일부 요소를 가져 오는 것일 수 있습니다 .

나는 더 잘 설명한다 :

서비스 파일입니다 .

// your-service-file.ts
import { helloWorld } from 'your-component-file.ts'

@Injectable()
export class CustomService() {
  helloWorld()
}

이것은 구성 요소 파일입니다 .

@Component({..})
export class CustomComponent {
  constructor(service: CustomService) { }
}

export function helloWorld() {
  console.log('hello world');
}

따라서 심볼이 동일한 구성 요소 안에 있지 않아도 동일한 파일 안에 있어도 문제가 발생합니다. 기호를 다른 곳으로 이동하면 (함수, 상수, 클래스 등이 될 수 있습니다.) 오류가 사라집니다.


1

각도 6 및 최신 버전의 경우 시도하십시오

@Injectable({
  providedIn: 'root'
})

.. 사이에 다른 줄이없는 서비스 클래스 바로 위

장점

  • 모든 모듈에 서비스를 추가 할 필요가 없습니다 ( "자동 발견"됨)
  • 서비스는 싱글 톤이 될 것입니다 (루트에 주입되기 때문에)

[ 각도 문서 ]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.