To działa dla mnie obecnie (2018-03, angular 5.2 with AoT, testowane w angular-cli i niestandardowej kompilacji webpacka):
Najpierw utwórz usługę do wstrzykiwania, która zawiera odniesienie do window:
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();
}
}
Teraz zarejestruj tę usługę w swoim głównym module AppModule, aby można ją było wstrzykiwać wszędzie:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
a później, gdzie należy wykonać wstrzyknięcie 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;
}
...
Możesz także chcieć dodać nativeDocument
i inne globalne do tej usługi w podobny sposób, jeśli używasz ich w swojej aplikacji.
edycja: Zaktualizowano sugestią Truchainza. edit2: Zaktualizowano dla Angular 2.1.2 edit3: Dodano uwagi AoT edit4: Dodanie opisu any
obejścia problemu
ORIGINAL EXCEPTION: No provider for Window!
. Jednak usunięcie go rozwiązało problem. Użycie tylko pierwszych 2 globalnych linii było dla mnie wystarczające.@Inject
pojawiały sięNo provider for Window
błędy. To całkiem fajne, że nie potrzebujesz instrukcji@Inject
!@Inject(Window)
aby to zadziałałowindow
, ale z usługą pomiędzy pozwala na usuwanie natywnychwindow
rzeczy w testach jednostkowych, a jak wspomniałeś dla SSR, można zapewnić alternatywną usługę, która ujawnia okno pozorowane / noop dla serwera. Powodem, dla którego wspominam o AOT, jest kilka wczesnych rozwiązań do zawijania okna, które zepsuły się w AOT po aktualizacji Angular.Wraz z wydaniem angular 2.0.0-rc.5 NgModule został wprowadzony. Poprzednie rozwiązanie przestało dla mnie działać. Oto, co zrobiłem, aby to naprawić:
app.module.ts:
W jakimś komponencie:
Możesz również użyć OpaqueToken zamiast ciągu „Window”
Edytować:
AppModule służy do ładowania aplikacji w main.ts w następujący sposób:
Aby uzyskać więcej informacji o NgModule, przeczytaj dokumentację Angular 2: https://angular.io/docs/ts/latest/guide/ngmodule.html
źródło
Możesz go po prostu wstrzyknąć po ustawieniu dostawcy:
źródło
window.var
zawartość strony się nie zmieniaMożesz pobrać okno z wstrzykniętego dokumentu.
źródło
Aby to działało w Angular 2.1.1, musiałem
@Inject
otworzyć okno za pomocą ciągu znakówa potem kpić z tego w ten sposób
i zwykle
@NgModule
tak to zapewniamźródło
W Angular RC4 następujące prace, które są kombinacją niektórych z powyższych odpowiedzi, w aplikacji root. T dodaj dostawców:
Następnie w usłudze itp. Wstrzyknij go do konstruktora
źródło
Przed deklaracją @Component też możesz to zrobić,
Kompilator faktycznie pozwoli ci teraz uzyskać dostęp do globalnej zmiennej okna, ponieważ zadeklarujesz ją jako zakładaną zmienną globalną o typie any.
Nie sugerowałbym jednak dostępu do okna w każdym miejscu aplikacji. Powinieneś tworzyć usługi, które uzyskują dostęp / modyfikują potrzebne atrybuty okna (i wstrzykują te usługi do swoich komponentów), aby określić zakres tego, co możesz zrobić z oknem, nie pozwalając im modyfikować cały obiekt okna.
źródło
Użyłem OpaqueToken dla ciągu znaków „Window”:
I używane tylko do importowania
WINDOW_PROVIDERS
w bootstrapie w Angular 2.0.0-rc-4.Ale wraz z wydaniem Angulara 2.0.0-rc.5 muszę stworzyć osobny moduł:
i właśnie zdefiniowano we właściwości Import mojego pliku głównego
app.module.ts
źródło
Angular 4 wprowadza InjectToken, a także tworzy token dla dokumentu o nazwie DOCUMENT . Myślę, że jest to oficjalne rozwiązanie i działa w AoT.
Używam tej samej logiki do stworzenia małej biblioteki o nazwie ngx-window-token aby zapobiec robieniu tego w kółko.
Użyłem go w innym projekcie i kompilowałem w AoT bez problemów.
Oto jak użyłem go w innym pakiecie
Tutaj jest plunker
W Twoim module
imports: [ BrowserModule, WindowTokenModule ]
W twoim komponencieconstructor(@Inject(WINDOW) _window) { }
źródło
Na dzień dzisiejszy (kwiecień 2016 r.) Kod w poprzednim rozwiązaniu nie działa, myślę, że można wstrzyknąć okno bezpośrednio do App.ts, a następnie zebrać potrzebne wartości do usługi globalnego dostępu w aplikacji, ale jeśli wolisz tworzyć i wprowadzać własne usługi, jest to o wiele prostsze rozwiązanie.
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
źródło
Oto inne rozwiązanie, które wpadłem niedawno po tym, jak zmęczyłem się pobieraniem
defaultView
zDOCUMENT
wbudowanego tokena i sprawdzaniem, czy jest pusty:źródło
@Inject(WINDOW) private _window: any
i używać go jak tokena iniekcyjnego DOKUMENTU dostarczonego przez Angular?To wystarczy
i robić
aby uszczęśliwić AOT
źródło
Istnieje możliwość bezpośredniego dostępu do obiektu okna poprzez dokument
źródło
Wiem, że pytanie brzmi, jak wstrzyknąć obiekt okna do komponentu, ale wydaje się, że robisz to tylko po to, aby dostać się do localStorage. Jeśli naprawdę chcesz tylko localStorage, dlaczego nie skorzystać z usługi, która to ujawnia, na przykład h5webstorage . Następnie komponent opiszesz jego rzeczywiste zależności, dzięki czemu Twój kod będzie bardziej czytelny.
źródło
To najkrótsza / najczystsza odpowiedź, jaką znalazłem podczas pracy z Angular 4 AOT
Źródło: https://github.com/angular/angular/issues/12631#issuecomment-274260009
źródło
Możesz użyć NgZone w Angular 4:
źródło
Dobrym pomysłem jest również oznaczenie tego
DOCUMENT
jako opcjonalnego. Zgodnie z dokumentacją Angular:Oto przykład użycia,
DOCUMENT
aby sprawdzić, czy przeglądarka obsługuje SVG:źródło
@maxisam dzięki za ngx-window-token . Robiłem coś podobnego, ale przeszedłem na twoje. To jest moja usługa do słuchania zdarzeń zmiany rozmiaru okna i powiadamiania subskrybentów.
Krótkie i słodkie, działa jak urok.
źródło
Pobieranie obiektu okna przez DI (Dependency Injection) nie jest dobrym pomysłem, gdy zmienne globalne są dostępne w całej aplikacji.
Ale jeśli nie chcesz używać obiektu okna, możesz również użyć
self
słowa kluczowego, które również wskazuje na obiekt okna.źródło
Niech to będzie proste, ludzie!
źródło
Właściwie bardzo łatwo jest uzyskać dostęp do obiektu okna, tutaj jest moim podstawowym komponentem i przetestowałem jego działanie
źródło