Angular 8과 9에서 'Window'와 Window를 제공하고 주입하는 것의 차이점은 무엇입니까?


10

이 버전을 사용하는 두 개의 Angular 프로젝트가 있습니다.

  • 9.0.0- 다음 6
  • 8.1.0

버전 9에서는 이것을 사용하여 window객체 를 제공하고 주입했습니다 .

@NgModule({
  providers: [
    {
      provide: Window,
      useValue: window
    },
  ]
})

export class TestComponent implements OnInit {
  constructor(@Inject(Window) private window: Window)
}

어느 것이 잘 작동합니까?


이 방법을 버전 8에 사용하면 컴파일하는 동안 경고와 오류가 발생했습니다.

경고 : TestComponent에 대한 모든 매개 변수를 해석 할 수 없습니다…

다음과 같이 작은 따옴표를 사용하여 해결했습니다.

@NgModule({
  providers: [
    {
      provide: 'Window',
      useValue: window
    },
  ]
})

export class TestComponent implements OnInit {
  constructor(@Inject('Window') private window: Window)
}

두 버전의 차이점은 무엇입니까?
이 문제를 일으키는 Angular 8과 9의 차이점은 무엇입니까?


현상금으로 나와 다른 사람들 이 Angular 및 다른 버전의 프레임 워크에서 공급자di 가 어떻게 작동하는지 더 잘 배우고 이해할 수있는 대답을 얻을 수 있기를 바랍니다 .
전등갓

답변:


6

앱이 서버 측 렌더링과 함께 작동하려면 창을 통해 토큰을 사용하는 것뿐만 아니라 전혀 참조하지 않고 SSR 친화적 인 방식 으로이 토큰을 생성하는 것이 좋습니다 window. Angular에는 DOCUMENT에 액세스하기위한 기본 제공 토큰이 document있습니다. 다음은 window토큰을 통해 프로젝트에서 사용할 수있는 내용입니다 .

import {DOCUMENT} from '@angular/common';
import {inject, InjectionToken} from '@angular/core';

export const WINDOW = new InjectionToken<Window>(
    'An abstraction over global window object',
    {
        factory: () => {
            const {defaultView} = inject(DOCUMENT);

            if (!defaultView) {
                throw new Error('Window is not available');
            }

            return defaultView;
        },
    },
);

대답 해 주셔서 감사합니다. 매우 유용하며 앞으로 이와 같은 솔루션을 사용할 것입니다.
전등갓

5

ValueProvider인터페이스 고려 :

export declare interface ValueProvider extends ValueSansProvider {
    /**
     * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.
     */
    provide: any;
    /**
     * When true, injector returns an array of instances. This is useful to allow multiple
     * providers spread across many files to provide configuration information to a common token.
     */
    multi?: boolean;
}

provide속성은 유형 any입니다. 즉, Window생성자에 포함 된 모든 개체가 그 안에 들어갈 수 있습니다. 객체는 실제로 중요하지 않으며 생성자에 매개 변수를 주입하는 데 사용해야하는 공급자를 식별하기위한 참조 만 중요합니다.

네이티브 Window생성자를 주입 토큰으로 사용하는 것은 좋은 습관으로 간주되어서는 안됩니다 . Window브라우저 환경에서 런타임에 존재 하기 때문에 컴파일 타임에 실패 declare하지만 TypeScript로 존재 하지만 Angular 8 컴파일러는 할당 이 완료 되었으므로 Window공급자와 Window생성자의 매개 변수 를 상호 연관시키기 위해 정적 코드 분석을 수행 할 수 없습니다. Window코드가 아닌 브라우저에 의해 왜 Angular 9에서 작동하는지 확실하지 않습니다 ...

종속성 제공자를 나타내는 고유 한 주입 토큰을 작성해야합니다. 이 주입 토큰은 다음 중 하나 여야합니다.

  • 전용 문자열 (당신이했던 것처럼 'Window')
  • 전용 InjectionToken. 예를 들어export const window = new InjectionToken<Window>('window');

이 반환하는 공장을 사용하는 것이 좋을 것이다, 그래서 또한, 각도 코드가 플랫폼 불가지론해야합니다 (브라우저에서와 Node.js를 서버뿐만 아니라 실행해야한다) window또는 undefined/ null후 처리 undefined/ null구성 요소의 경우.


1
자세한 답변을 주셔서 감사합니다. 많은 도움이되었습니다.
전등갓

1
아주 좋아요! 감사. 방금 Angular 문서 (v8 및 v9)를 확인했으며 문자열을 사용하는 단일 예제를 찾지 못했습니다. :( 실제로 문서에서 이것을 설명해야합니다!
Zaphoid
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.