TypeScript에서 localstorage
. window
Angular 1.x와 같은 전역 변수를 참조하고 싶지 않기 때문에 브라우저 개체에 대한 참조를 내 서비스 에 삽입하고 싶습니다 $window
.
어떻게하나요?
답변
이것은 현재 나를 위해 일하고 있습니다 (2018-03, AoT가있는 angular 5.2, angular-cli 및 사용자 정의 웹 팩 빌드에서 테스트 됨).
먼저 창에 대한 참조를 제공하는 주입 가능한 서비스를 만듭니다.
import { Injectable } from '@angular/core';
// This interface is optional, showing how you can add strong typings for custom globals.
// Just use "Window" as the type if you don't have custom global stuff
export interface ICustomWindow extends Window {
__custom_global_stuff: string;
}
function getWindow (): any {
return window;
}
@Injectable()
export class WindowRefService {
get nativeWindow (): ICustomWindow {
return getWindow();
}
}
이제 해당 서비스를 루트 AppModule에 등록하여 모든 곳에 삽입 할 수 있습니다.
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
그런 다음 나중에 주입해야 할 부분 window
:
import { Component} from '@angular/core';
import { WindowRefService, ICustomWindow } from './window-ref.service';
@Component({ ... })
export default class MyCoolComponent {
private _window: ICustomWindow;
constructor (
windowRef: WindowRefService
) {
this._window = windowRef.nativeWindow;
}
public doThing (): void {
let foo = this._window.XMLHttpRequest;
let bar = this._window.__custom_global_stuff;
}
...
nativeDocument
응용 프로그램에서 사용하는 경우 유사한 방식으로이 서비스에 및 기타 전역 을 추가 할 수도 있습니다 .
편집 : Truchainz 제안으로 업데이트되었습니다. edit2 : angular 2.1.2에 대해 업데이트 됨 edit3 : AoT 노트 추가 edit4 : any
유형 해결 방법 note edit5 : 다른 빌드로 이전 솔루션을 사용할 때 발생하던 오류를 수정하는 WindowRefService를 사용하도록 업데이트 된 솔루션 edit6 : 예제 사용자 지정 창 타이핑 추가
답변
angular 2.0.0-rc.5의 출시와 함께 NgModule이 도입되었습니다. 이전 솔루션이 작동을 멈췄습니다. 이것은 내가 그것을 고치기 위해 한 일입니다.
app.module.ts :
@NgModule({
providers: [
{ provide: 'Window', useValue: window }
],
declarations: [...],
imports: [...]
})
export class AppModule {}
일부 구성 요소에서 :
import { Component, Inject } from '@angular/core';
@Component({...})
export class MyComponent {
constructor (@Inject('Window') window: Window) {}
}
OpaqueToken을 사용할 수도 있습니다.문자열 ‘Window’대신
편집하다:
AppModule은 다음과 같이 main.ts에서 애플리케이션을 부트 스트랩하는 데 사용됩니다.
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
NgModule에 대한 자세한 내용은 Angular 2 설명서를 참조하십시오 . https://angular.io/docs/ts/latest/guide/ngmodule.html
답변
제공자를 설정 한 후에 주입 할 수 있습니다.
import {provide} from 'angular2/core';
bootstrap(..., [provide(Window, {useValue: window})]);
constructor(private window: Window) {
// this.window
}
답변
삽입 된 문서에서 창을 가져올 수 있습니다.
import { Inject } from '@angular/core';
import { DOCUMENT } from '@angular/common';
export class MyClass {
constructor(@Inject(DOCUMENT) private document: Document) {
this.window = this.document.defaultView;
}
check() {
console.log(this.document);
console.log(this.window);
}
}
답변
Angular 2.1.1에서 작동하려면 @Inject
문자열을 사용하여 창을 만들어야했습니다.
constructor( @Inject('Window') private window: Window) { }
다음과 같이 조롱
beforeEach(() => {
let windowMock: Window = <any>{ };
TestBed.configureTestingModule({
providers: [
ApiUriService,
{ provide: 'Window', useFactory: (() => { return windowMock; }) }
]
});
보통 @NgModule
이렇게 제공합니다
{ provide: 'Window', useValue: window }
답변
Angular RC4에서는 위의 답변 중 일부가 결합 된 다음 작업이 루트 app.ts에서 공급자를 추가합니다.
@Component({
templateUrl: 'build/app.html',
providers: [
anotherProvider,
{ provide: Window, useValue: window }
]
})
그런 다음 서비스 등에서 생성자에 삽입하십시오.
constructor(
@Inject(Window) private _window: Window,
)
답변
@Component 선언 전에도 그렇게 할 수 있습니다.
declare var window: any;
컴파일러는 실제로 전역 창 변수에 액세스 할 수 있도록합니다. 이는 any 유형의 가정 된 전역 변수로 선언하기 때문입니다.
응용 프로그램의 모든 곳에서 창에 액세스하는 것은 권장하지 않습니다. 필요한 창 속성에 액세스 / 수정하는 서비스를 만들고 구성 요소에 해당 서비스를 삽입하여 창으로 할 수있는 작업을 수정하지 않고 범위를 지정해야합니다. 전체 창 개체.