Cela fonctionne pour moi actuellement (2018-03, angular 5.2 avec AoT, testé dans angular-cli et une version webpack personnalisée):
Tout d'abord, créez un service injectable qui fournit une référence à 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();
}
}
Maintenant, enregistrez ce service avec votre AppModule racine afin qu'il puisse être injecté partout:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
puis plus tard où vous devez injecter 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;
}
...
Vous pouvez également souhaiter ajouter d' nativeDocument
autres globaux à ce service de la même manière si vous les utilisez dans votre application.
edit: Mis à jour avec la suggestion de Truchainz. edit2: Mise à jour pour angular 2.1.2 edit3: Ajout de notes AoT edit4: Ajout de any
note de contournement de type edit5: Mise à jour de la solution pour utiliser un WindowRefService qui corrige une erreur que j'obtenais lors de l'utilisation de la solution précédente avec une version différente edit6: ajout d'un exemple de saisie de fenêtre personnalisée
ORIGINAL EXCEPTION: No provider for Window!
. Cependant, sa suppression a résolu le problème pour moi. Utiliser uniquement les 2 premières lignes globales me suffisait.@Inject
je reçoive desNo provider for Window
erreurs. C'est plutôt sympa de ne pas avoir besoin du manuel@Inject
!@Inject(Window)
pour que cela fonctionnewindow
, mais avec le service entre les deux, il permet de supprimer deswindow
éléments natifs dans les tests unitaires, et comme vous le mentionnez pour SSR, un service alternatif peut être fourni qui expose une fenêtre fictive / noop pour le serveur. La raison pour laquelle je mentionne AOT est que plusieurs des premières solutions pour envelopper la fenêtre se sont cassées dans AOT lors de la mise à jour Angular.Avec la sortie d'angular 2.0.0-rc.5, NgModule a été introduit. La solution précédente a cessé de fonctionner pour moi. Voici ce que j'ai fait pour y remédier:
app.module.ts:
Dans certains composants:
Vous pouvez également utiliser un OpaqueToken au lieu de la chaîne 'Window'
Éditer:
L'AppModule est utilisé pour démarrer votre application dans main.ts comme ceci:
Pour plus d'informations sur NgModule, lisez la documentation Angular 2: https://angular.io/docs/ts/latest/guide/ngmodule.html
la source
Vous pouvez simplement l'injecter après avoir défini le fournisseur:
la source
window.var
contenu de la page ne change pasVous pouvez obtenir une fenêtre à partir du document injecté.
la source
Pour le faire fonctionner sur Angular 2.1.1, j'ai dû
@Inject
fenêtre en utilisant une chaîneet puis se moquer de ça comme ça
et dans l'ordinaire
@NgModule
je le fournis comme çala source
Dans Angular RC4, les travaux suivants, qui sont une combinaison de certaines des réponses ci-dessus, dans votre application racine, ajoutez-y les fournisseurs:
Puis dans votre service, etc. injectez-le dans le constructeur
la source
Avant la déclaration @Component, vous pouvez le faire aussi,
Le compilateur vous permettra en fait d'accéder à la variable de fenêtre globale maintenant puisque vous la déclarez comme une variable globale supposée de type any.
Cependant, je ne suggérerais pas d'accéder à la fenêtre partout dans votre application, vous devriez créer des services qui accèdent / modifient les attributs de fenêtre nécessaires (et injectent ces services dans vos composants) pour définir ce que vous pouvez faire avec la fenêtre sans les laisser modifier le objet de la fenêtre entière.
la source
J'ai utilisé OpaqueToken pour la chaîne 'Window':
Et utilisé juste pour importer
WINDOW_PROVIDERS
en bootstrap dans Angular 2.0.0-rc-4.Mais avec la sortie d'Angular 2.0.0-rc.5, je dois créer un module séparé:
et juste défini dans la propriété importations de ma main
app.module.ts
la source
À partir d'aujourd'hui (avril 2016), le code de la solution précédente ne fonctionne pas, je pense qu'il est possible d'injecter une fenêtre directement dans App.ts, puis de rassembler les valeurs dont vous avez besoin dans un service pour un accès global dans l'application, mais si vous préférez créer et injecter votre propre service, une solution plus simple est la suivante.
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
la source
Angular 4 introduit InjectToken et crée également un jeton pour le document appelé DOCUMENT . Je pense que c'est la solution officielle et cela fonctionne dans AoT.
J'utilise la même logique pour créer une petite bibliothèque appelée ngx-window-token pour éviter de faire cela encore et encore.
Je l'ai utilisé dans un autre projet et construit dans AoT sans problèmes.
Voici comment je l'ai utilisé dans un autre package
Voici le plunker
Dans votre module
imports: [ BrowserModule, WindowTokenModule ]
Dans votre composantconstructor(@Inject(WINDOW) _window) { }
la source
Voici une autre solution que j'ai proposée récemment après avoir été fatigué d'obtenir
defaultView
duDOCUMENT
jeton intégré et de le vérifier pour null:la source
@Inject(WINDOW) private _window: any
et utilisez-le comme le jeton d'injection DOCUMENT fourni par Angular?Il suffit de faire
et fait
pour rendre AOT heureux
la source
Il est possible d'accéder directement à l'objet de la fenêtre via le document
la source
Je sais que la question est de savoir comment injecter l'objet window dans un composant, mais vous faites cela juste pour accéder à localStorage, semble-t-il. Si vous voulez vraiment juste localStorage, pourquoi ne pas utiliser un service qui expose exactement cela, comme h5webstorage . Ensuite, votre composant décrira ses véritables dépendances, ce qui rend votre code plus lisible.
la source
C'est la réponse la plus courte / la plus propre que j'ai trouvée en travaillant avec Angular 4 AOT
Source: https://github.com/angular/angular/issues/12631#issuecomment-274260009
la source
Vous pouvez utiliser NgZone sur Angular 4:
la source
C'est également une bonne idée de marquer le
DOCUMENT
comme facultatif. Selon les documents Angular:Voici un exemple d'utilisation de
DOCUMENT
pour voir si le navigateur prend en charge SVG:la source
@maxisam merci pour ngx-window-token . Je faisais quelque chose de similaire mais je suis passé au vôtre. C'est mon service pour écouter les événements de redimensionnement de fenêtre et notifier les abonnés.
Court et doux et fonctionne comme un charme.
la source
Obtenir un objet fenêtre via DI (Dependency Injection) n'est pas une bonne idée lorsque les variables globales sont accessibles dans toute l'application.
Mais si vous ne souhaitez pas utiliser d'objet window, vous pouvez également utiliser un
self
mot-clé qui pointe également vers l'objet window.la source
Restez simple, les amis!
la source
En fait, il est très simple d'accéder à un objet de fenêtre, voici mon composant de base et je l'ai testé
la source