Dies funktioniert derzeit für mich (2018-03, Angular 5.2 mit AoT, getestet in Angular-CLI und einem benutzerdefinierten Webpack-Build):
Erstellen Sie zunächst einen injizierbaren Dienst, der einen Verweis auf das Fenster enthält:
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();
}
}
Registrieren Sie diesen Dienst jetzt bei Ihrem Root-AppModule, damit er überall injiziert werden kann:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
und dann später, wo Sie injizieren müssen 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;
}
...
Möglicherweise möchten nativeDocument
Sie diesem Service auch ähnliche globale Elemente hinzufügen , wenn Sie diese in Ihrer Anwendung verwenden.
bearbeiten: Aktualisiert mit Truchainz Vorschlag. edit2: Aktualisiert für Angular 2.1.2 edit3: AoT-Notizen hinzugefügt edit4: Hinzufügen von Problemumgehungsnotizen für Notizen edit5: Die any
Lösung wurde aktualisiert, um einen WindowRefService zu verwenden, der einen Fehler behebt, den ich bei der Verwendung einer früheren Lösung mit einem anderen Build erhalten habe. edit6: Hinzufügen einer benutzerdefinierten Fenstertypisierung
ORIGINAL EXCEPTION: No provider for Window!
. Das Entfernen hat das Problem jedoch für mich behoben. Es hat mir gereicht, nur die ersten beiden globalen Linien zu verwenden.@Inject
ichNo provider for Window
Fehler bekam. Das ist ziemlich schön, das Handbuch nicht zu brauchen@Inject
!@Inject(Window)
arbeitenwindow
, aber mit dem dazwischen liegenden Dienst können native Inhalte in Komponententests gelöscht werden.window
Wie Sie für SSR erwähnen, kann ein alternativer Dienst bereitgestellt werden, der ein Mock / Noop-Fenster für den Server anzeigt. Der Grund, warum ich AOT erwähne, sind einige der frühen Lösungen für das Umbrechen von Fenstern, die bei der Aktualisierung von Angular in AOT kaputt gegangen sind.Mit der Freigabe von Angular 2.0.0-rc.5 wurde NgModule eingeführt. Die vorherige Lösung hat bei mir nicht mehr funktioniert. Folgendes habe ich getan, um das Problem zu beheben:
app.module.ts:
In einigen Komponenten:
Sie können auch ein OpaqueToken anstelle der Zeichenfolge 'Window' verwenden.
Bearbeiten:
Das AppModule wird verwendet, um Ihre Anwendung in main.ts wie folgt zu booten:
Weitere Informationen zu NgModule finden Sie in der Angular 2-Dokumentation: https://angular.io/docs/ts/latest/guide/ngmodule.html
quelle
Sie können es einfach injizieren, nachdem Sie den Anbieter festgelegt haben:
quelle
window.var
den Inhalt der Seite ändere, ändert sich nichtSie können Fenster aus injiziertem Dokument erhalten.
quelle
Damit es in Angular 2.1.1 funktioniert, musste ich
@Inject
eine Zeichenfolge verwendenund dann verspotten Sie es so
und im gewöhnlichen biete
@NgModule
ich es so anquelle
In Angular RC4 funktioniert das Folgende, was eine Kombination einiger der oben genannten Antworten ist. Fügen Sie in Ihren Root-Apps die Anbieter hinzu:
Dann in Ihren Dienst usw. in den Konstruktor injizieren
quelle
Vor der @ Component-Deklaration können Sie dies auch tun.
Der Compiler lässt Sie dann tatsächlich auf die globale Fenstervariable zugreifen, da Sie sie als angenommene globale Variable mit dem Typ any deklarieren.
Ich würde jedoch nicht empfehlen, überall in Ihrer Anwendung auf das Fenster zuzugreifen. Sie sollten Dienste erstellen, die auf die erforderlichen Fensterattribute zugreifen / diese ändern (und diese Dienste in Ihre Komponenten einfügen), um zu erfassen, was Sie mit dem Fenster tun können, ohne dass sie das Fenster ändern können ganzes Fensterobjekt.
quelle
Ich habe OpaqueToken für die ' Window' -Zeichenfolge verwendet:
Und nur zum Importieren
WINDOW_PROVIDERS
in Bootstrap in Angular 2.0.0-rc-4 verwendet.Aber mit der Veröffentlichung von Angular 2.0.0-rc.5 muss ich ein separates Modul erstellen:
und gerade in der Import-Eigenschaft meines Haupt definiert
app.module.ts
quelle
Ab heute (April 2016) funktioniert der Code in der vorherigen Lösung nicht mehr. Ich denke, es ist möglich, Fenster direkt in App.ts einzufügen und dann die Werte, die Sie benötigen, in einem Dienst für den globalen Zugriff in der App zu sammeln Wenn Sie es vorziehen, Ihren eigenen Service zu erstellen und einzufügen, ist dies eine einfachere Lösung.
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
quelle
Angular 4 führt InjectToken ein und erstellt ein Token für das Dokument DOCUMENT . Ich denke, dies ist die offizielle Lösung und sie funktioniert in AoT.
Ich verwende dieselbe Logik, um eine kleine Bibliothek namens ngx-window-token zu erstellen , um dies immer wieder zu verhindern.
Ich habe es in anderen Projekten verwendet und AoT ohne Probleme eingebaut.
Hier ist, wie ich es in einem anderen Paket verwendet habe
Hier ist der Plunker
In Ihrem Modul
imports: [ BrowserModule, WindowTokenModule ]
In Ihrer Komponenteconstructor(@Inject(WINDOW) _window) { }
quelle
Es besteht die Möglichkeit, über das Dokument direkt auf das Objekt des Fensters zuzugreifen
quelle
Hier ist eine andere Lösung, die ich kürzlich gefunden habe, nachdem ich es satt hatte,
defaultView
von einemDOCUMENT
eingebauten Token zu kommen und es auf null zu überprüfen:quelle
@Inject(WINDOW) private _window: any
und verwenden Sie es wie das von Angular bereitgestellte DOKUMENT-Injektions-Token?Ich weiß, dass die Frage ist, wie das Fensterobjekt in eine Komponente eingefügt wird, aber Sie tun dies nur, um zu localStorage zu gelangen, wie es scheint. Wenn Sie wirklich nur localStorage möchten, können Sie einen Dienst wie h5webstorage verwenden, der genau das verfügbar macht . Anschließend beschreibt Ihre Komponente die tatsächlichen Abhängigkeiten, wodurch Ihr Code besser lesbar wird.
quelle
Dies ist die kürzeste / sauberste Antwort, die ich bei der Arbeit mit Angular 4 AOT gefunden habe
Quelle: https://github.com/angular/angular/issues/12631#issuecomment-274260009
quelle
Es ist genug zu tun
und TU
AOT glücklich machen
quelle
Sie können NgZone für Angular 4 verwenden:
quelle
Es ist auch eine gute Idee, das
DOCUMENT
als optional zu markieren . Gemäß den Angular-Dokumenten:Hier ist ein Beispiel für die Verwendung von
DOCUMENT
, um festzustellen, ob der Browser SVG-Unterstützung bietet:quelle
@maxisam danke für ngx-window-token . Ich habe etwas Ähnliches gemacht, aber zu dir gewechselt. Dies ist mein Dienst zum Abhören von Ereignissen zur Größenänderung von Fenstern und zum Benachrichtigen von Abonnenten.
Kurz und bündig und wirkt wie ein Zauber.
quelle
Das Abrufen von Fensterobjekten über DI (Dependency Injection) ist keine gute Idee, wenn auf globale Variablen in der gesamten Anwendung zugegriffen werden kann.
Wenn Sie jedoch kein Fensterobjekt verwenden möchten, können Sie auch ein
self
Schlüsselwort verwenden, das auch auf ein Fensterobjekt verweist.quelle
Halte es einfach, Leute!
quelle
Eigentlich ist der sehr einfache Zugriff auf das Fensterobjekt hier meine Grundkomponente und ich habe getestet, ob es funktioniert
quelle