J'ai deux projets Angular utilisant ces versions:
- 9.0.0-next.6
- 8.1.0
Dans la version 9, j'ai utilisé ceci pour fournir et injecter l' window
objet:
@NgModule({
providers: [
{
provide: Window,
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject(Window) private window: Window)
}
Ce qui fonctionne bien.
Cette approche de la version 8 a généré des avertissements et des erreurs lors de la compilation:
Avertissement: impossible de résoudre tous les paramètres de TestComponent…
Je l'ai résolu en utilisant des guillemets simples, comme ceci:
@NgModule({
providers: [
{
provide: 'Window',
useValue: window
},
]
})
export class TestComponent implements OnInit {
constructor(@Inject('Window') private window: Window)
}
Quelle est la différence entre les deux versions?
Quelle est la différence entre Angular 8 et 9 qui cause cette chose?
Réponses:
Pour que votre application fonctionne avec le rendu côté serveur, je vous suggère non seulement d'utiliser la fenêtre via le jeton, mais également de créer ce jeton de manière conviviale SSR, sans référencer
window
du tout. Angular a unDOCUMENT
jeton intégré pour accéderdocument
. Voici ce que j'ai trouvé pour mes projets à utiliserwindow
via des jetons:la source
Considérant l'
ValueProvider
interface:La
provide
propriété est de typeany
. Cela signifie que tout objet (y compris leWindow
constructeur) peut y pénétrer. L'objet n'a en fait pas d'importance, seule la référence compte pour identifier le fournisseur à utiliser pour injecter un paramètre dans un constructeur.Il ne doit pas être considéré comme une bonne pratique d'utiliser le
Window
constructeur natif comme jeton d'injection. Il échoue au moment de la compilation, car ilWindow
existe au moment de l'exécution dans un environnement de navigateur, il existe également en tant que TypeScript,declare
mais le compilateur Angular 8 ne peut pas faire d'analyse de code statique pour corréler les paramètresWindow
dans les fournisseurs etWindow
dans les paramètres du constructeur, car l'affectation deWindow
est effectuée par le navigateur, pas par le code. Je ne sais pas pourquoi cela fonctionne dans Angular 9, cependant ...Vous devez créer votre propre jeton d'injection qui représente le fournisseur de dépendances. Ce jeton d'injection doit être:
'Window'
)InjectionToken
. Par exempleexport const window = new InjectionToken<Window>('window');
De plus, le code angulaire devrait être indépendant de la plate-forme (devrait également être exécutable dans un navigateur et sur un serveur Node.js), il serait donc préférable d'utiliser une usine qui renvoie
window
ouundefined
/null
, puis de gérer leundefined
/null
case dans les composants.la source