2016-06-30 2 views
2

이것은 특별한 경우 (브라우저 네이티브 윈도우 객체 삽입) 일 수 있지만 그럼에도 불구하고 왜 내 클래스에 이미 @Injectable() 데코레이터가있는 경우 왜 @Inject() 매개 변수 데코레이터가 필요한지 혼란스러워합니다. 왜이 angular2 예제에서 @inject가 필요한가요?

이 간단한 예를 보자

import { provide, bootstrap, Injectable, Inject } from '@angular/core'; 


@Injectable() 
export class Token { 
    private token: string; 

    public constructor(token: string, window: Window) { 
    this.token = window.atob(token); 
    }; 

    public getToken(): string { 
    return this.token; 
    } 
} 


@Injectable() 
export class TokenFactory { 
    private window: Window; 

    public constructor(window: Window) { 
    this.window = window; 
    } 

    public createToken(token: string): Token { 
    return new Token(token, this.window); 
    } 
} 


@Component({ 
    template: ` 
    <p *ngFor="let token of tokens"> 
     Encoded: {{token.getToken()}} 
    </p> 
    `, 
    providers: [ TokenFactory ] 
}) 
class MainComponent { 
    public tokens: Token[]; 

    public constructor(factory: TokenFactory) { 
    this.tokens = [ 
     factory.create('token-1'), 
     factory.create('token-2') 
    ]; 
    }; 
} 


bootstrap(
    MainComponent, [ 
    provide(Window, { useValue: window }) 
]); 

개요 : 우리는 구성 요소 또는 다른 서비스 (그래서 아무 싱글) 내부에 여러 번 존재할 수있는 개체를 나타내는 토큰 클래스가 있습니다. 토큰 클래스는 글로벌 윈도우 객체 (예 : base64 인코딩)에 따라 다릅니다. 이 테스트를 가능하게하려면 토큰 서비스에서 직접 사용하는 대신 부트 스트랩 중 글로벌 window object에 대한 앱 전체 공급자를 정의합니다.

주 구성 요소는 토큰을 동적으로 작성해야하므로 간단한 기본 서비스 (작성 중에 토큰 클래스를 전달하는 데 필요한)를 제공하는 간단한 공장 서비스 TokenFactory을 작성하고 삽입해야합니다.

문제점 : 오류

Can't resolve all parameters for TokenFactory: (?). 

으로 브라우저에서 실행되지만 공장 생성자 파라미터에 @Inject (윈도우) 장식을 추가로 개선 할 수있는 경우 이것은 실패한다.

이제 Injectable 데코레이터 인 으로 클래스를 꾸밀 때 주입 장식이 typescript에 필요하지 않다고 설명 했으므로 약간 혼란 스럽습니다. @Inject()를 사용하지 않고 예제가 실패하는 이유는 무엇입니까? 장식가?

구성 :emitDecoratorMetadataexperimentalDecorators 설정이 활성화되어 내가 TSC 1.8.10angular2 rc.3을 사용하고 있습니다.


PS :나는 또한 일반적인 디자인 개선을위한 개방적이야.

(예. 내가 아마 단지 토큰 인터페이스가 아닌 학급 전체 수출 것 생산 시나리오)에 대한 유형 string을 질문 실제로 무슨에 관하여 나에게

+0

Window 클래스가 정의 된 위치와 가져 오기 방법에 대해 자세히 알려주시겠습니까? 감사! –

+0

_window_ (lover case)로 표시되는 전역 [window object] (https://developer.mozilla.org/en-US/docs/Web/API/Window) 브라우저입니다. 부트 스트랩 (bootstrap) 중에 맨 아래에 주입됩니다. 흠 ..., typescript/angular가 Window 이름 속성을 혼동시킬 수 있기 때문에 제공자 이름이 문자열이거나 OpaqueToken이 아니면 안된다. – TomKeegasi

+0

컴파일 타임 (tsc)이 아닌 런타임 (브라우저) 오류입니다 ... – TomKeegasi

답변

5

그것은 불분명를하지만

사장님 주사의 생성자 매개 변수는 @Inject(...)

@Injectable() 
export class Token { 
    private token: string; 

    public constructor(token: string, window: Window) { // <<== invalid 
    this.token = window.atob(token); 
    }; 

    public getToken(): string { 
    return this.token; 
    } 
} 

없이 이해가되지 않습니다하지만 당신은 그것을 사용하고 있기 때문에 e

new Token(token, this.window); 

그냥이 클래스에서 @Injectable()을 제거해야합니다.오류 메시지에 대한


: Window 제대로 가져 오지 않습니다처럼 보이는하거나 유형하지만 OpaqueToken 또는 string 없습니다.

@Inject()은 종속성 삽입시 매개 변수 유형과 다른 키를 사용해야하는 경우 필요합니다. 귀하의 경우에는 Window이 유형 (클래스)이 아니므로 사용하면 작동하지 않습니다.

+3

_token_ 매개 변수가 의도하지 않았으므로 좋은 캐치, 토큰 클래스의 주사를 삭제해야합니다. 실제로는 입력 매개 변수가 더 많이 주입됩니다. 창 _object_은 브라우저에서 가져온 것이므로 (메타 데이터 없음) 아마도 장식되어 있지 않으므로 각도는 팩토리 창 매개 변수의 인젝터 도우미가 필요합니다. 맞아. – TomKeegasi