Tengo dos proyectos angulares que usan estas versiones:
- 9.0.0-siguiente.6
- 8.1.0
En la versión 9 usé esto para proporcionar e inyectar el window
objeto:
@NgModule({
providers: [
{
provide: Window,
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject(Window) private window: Window)
}
Que funciona bien.
Tomando este enfoque a la versión 8 arrojó advertencias y errores durante la compilación:
Advertencia: no se pueden resolver todos los parámetros para TestComponent ...
Lo resolví usando comillas simples, como esta:
@NgModule({
providers: [
{
provide: 'Window',
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject('Window') private window: Window)
}
¿Cuál es la diferencia entre ambas versiones?
¿Cuál es la diferencia en Angular 8 y 9 que causa esto?
javascript
angular
typescript
dependency-injection
angular8
pantalla de lámpara
fuente
fuente
Respuestas:
Para que su aplicación funcione con Renderizado del lado del servidor, le sugiero que no solo use la ventana a través del token, sino que también cree este token de manera amigable con SSR, sin hacer referencia alguna
window
. Angular tieneDOCUMENT
token incorporado para accederdocument
. Esto es lo que se me ocurrió para que mis proyectos lo usen awindow
través de tokens:fuente
Teniendo en cuenta la
ValueProvider
interfaz:La
provide
propiedad es de tipoany
. Eso significa que cualquier objeto (incluido elWindow
constructor) puede ir dentro de él. El objeto en realidad no importa, solo la referencia importa para identificar qué proveedor debe usarse para inyectar un parámetro en un constructor.No debe considerarse una buena práctica utilizar el
Window
constructor nativo como token de inyección. Falla en tiempo de compilación porqueWindow
existe en tiempo de ejecución en un entorno de navegador, también existe como TypeScriptdeclare
pero el compilador Angular 8 no puede hacer análisis de código estático para correlacionar los parámetrosWindow
en los proveedores yWindow
en los parámetros de un constructor, ya que la asignación deWindow
se realiza por el navegador, no por el código. Sin embargo, no estoy seguro de por qué funciona en Angular 9 ...Debe crear su propio token de inyección que represente al proveedor de dependencia. Esta ficha de inyección debe ser:
'Window'
)InjectionToken
. Por ejemploexport const window = new InjectionToken<Window>('window');
Además, el código angular debe ser independiente de la plataforma (debe ser ejecutable en un navegador y también en un servidor Node.js), por lo que sería mejor usar una fábrica que devuelva
window
oundefined
/null
, luego manejar el casoundefined
/null
en los componentes.fuente