Esto me funciona actualmente (2018-03, angular 5.2 con AoT, probado en angular-cli y una compilación de paquete web personalizado):
Primero, cree un servicio inyectable que proporcione una referencia a la ventana:
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();
}
}
Ahora, registre ese servicio con su AppModule raíz para que pueda inyectarse en todas partes:
import { WindowRefService } from './window-ref.service';
@NgModule({
providers: [
WindowRefService
],
...
})
export class AppModule {}
y luego donde necesitas inyectar 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;
}
...
También es posible que desee agregar nativeDocument
y otros globales a este servicio de una manera similar si los usa en su aplicación.
editar: actualizado con sugerencia de Truchainz. edit2: Actualizado para angular 2.1.2 edit3: Se agregaron notas de AoT edit4: Añadiendo el any
tipo de nota de solución alternativa edit5: Solución actualizada para usar un WindowRefService que corrige un error que recibía al usar la solución anterior con una compilación diferente edit6: agregando un ejemplo de escritura de ventana personalizada
ORIGINAL EXCEPTION: No provider for Window!
. Sin embargo, quitarlo solucionó el problema. Usar solo las 2 primeras líneas globales fue suficiente para mí.@Inject
que aparecieranNo provider for Window
errores. ¡Eso es bastante bueno no necesitar el manual@Inject
!@Inject(Window)
para que esto funcionarawindow
, pero con el servicio intermedio permite eliminarwindow
cosas nativas en pruebas unitarias, y como mencionas para SSR, se puede proporcionar un servicio alternativo que expone una ventana simulada / noop para el servidor. La razón por la que menciono AOT es que varias de las primeras soluciones para envolver la ventana se rompieron en AOT cuando se actualizó Angular.Con el lanzamiento de angular 2.0.0-rc.5 se introdujo NgModule. La solución anterior dejó de funcionar para mí. Esto es lo que hice para solucionarlo:
app.module.ts:
En algún componente:
También puede usar un OpaqueToken en lugar de la cadena 'Ventana'
Editar:
El AppModule se usa para arrancar su aplicación en main.ts de esta manera:
Para obtener más información sobre NgModule, lea la documentación de Angular 2: https://angular.io/docs/ts/latest/guide/ngmodule.html
fuente
Puede inyectarlo después de haber configurado el proveedor:
fuente
window.var
contenido de la página no cambiaPuede obtener una ventana del documento inyectado.
fuente
Para que funcione en Angular 2.1.1 tuve que hacer una
@Inject
ventana usando una cadenay luego burlarte de esto
y en lo ordinario
@NgModule
lo proporciono asífuente
En Angular RC4 funciona lo siguiente, que es una combinación de algunas de las respuestas anteriores, en su aplicación raíz, agregue los proveedores:
Luego, en su servicio, etc.inyectelo en el constructor
fuente
Antes de la declaración @Component, también puede hacerlo,
El compilador en realidad le permitirá acceder a la variable de ventana global ahora, ya que la declara como una variable global asumida con el tipo any.
Sin embargo, no sugeriría acceder a la ventana en todas partes de su aplicación, debe crear servicios que accedan / modifiquen los atributos de ventana necesarios (e inyecte esos servicios en sus componentes) para determinar lo que puede hacer con la ventana sin permitirles modificar el todo el objeto de la ventana.
fuente
Solía OpaqueToken para la cadena 'Ventana':
Y se usa solo para importar
WINDOW_PROVIDERS
en bootstrap en Angular 2.0.0-rc-4.Pero con el lanzamiento de Angular 2.0.0-rc.5 necesito crear un módulo separado:
y acaba de definir en la propiedad de importaciones de mi principal
app.module.ts
fuente
A partir de hoy (abril de 2016), el código de la solución anterior no funciona, creo que es posible inyectar la ventana directamente en App.ts y luego recopilar los valores que necesita en un servicio para el acceso global en la aplicación, pero si prefiere crear e inyectar su propio servicio, una solución mucho más sencilla es esta.
https://gist.github.com/WilldelaVega777/9afcbd6cc661f4107c2b74dd6090cebf
fuente
Angular 4 introduce InjectToken y también crean un token para el documento llamado DOCUMENTO . Creo que esta es la solución oficial y funciona en AoT.
Utilizo la misma lógica para crear una pequeña biblioteca llamada ngx-window-token para evitar hacer esto una y otra vez.
Lo he usado en otro proyecto y lo construí en AoT sin problemas.
Así es como lo usé en otro paquete
Aquí está el plunker
En tu módulo
imports: [ BrowserModule, WindowTokenModule ]
En tu componenteconstructor(@Inject(WINDOW) _window) { }
fuente
Es suficiente para hacer
y hacer
para hacer feliz a AOT
fuente
Existe la posibilidad de acceder directamente al objeto de la ventana a través del documento.
fuente
Aquí hay otra solución que se me ocurrió poco después de que llegué cansado de recibir
defaultView
deDOCUMENT
una función de token y comprueba si existe alguna nulo:fuente
@Inject(WINDOW) private _window: any
y usarlo como el token de inyección de DOCUMENTO proporcionado por Angular?Sé que la pregunta es cómo inyectar el objeto de la ventana en un componente, pero parece que estás haciendo esto solo para llegar a localStorage. Si realmente solo desea localStorage, ¿por qué no utilizar un servicio que exponga precisamente eso, como h5webstorage ? Luego, su componente describirá sus dependencias reales, lo que hace que su código sea más legible.
fuente
Esta es la respuesta más corta / limpia que he encontrado trabajando con Angular 4 AOT
Fuente: https://github.com/angular/angular/issues/12631#issuecomment-274260009
fuente
Puede usar NgZone en Angular 4:
fuente
También es una buena idea marcar
DOCUMENT
como opcional. Según los documentos de Angular:A continuación, se muestra un ejemplo del uso de
DOCUMENT
para ver si el navegador es compatible con SVG:fuente
@maxisam gracias por ngx-window-token . Estaba haciendo algo similar, pero cambié al tuyo. Este es mi servicio para escuchar eventos de cambio de tamaño de ventana y notificar a los suscriptores.
Corto y dulce y funciona a las mil maravillas.
fuente
Obtener un objeto de ventana a través de DI (inyección de dependencia) no es una buena idea cuando las variables globales son accesibles en toda la aplicación.
Pero si no desea usar el objeto de ventana, también puede usar una
self
palabra clave que también apunta al objeto de ventana.fuente
¡Mantenlo simple, amigos!
fuente
En realidad, es muy simple acceder al objeto de la ventana. Aquí está mi componente básico y lo probé.
fuente