在 Angular 8 和 9 中提供和注入 'Window' 与 Window 有什么区别?

我有两个使用这些版本的 Angular 项目:


9.0.0-next.6

8.1.0

在版本 9 中,我使用它来提供和注入window对象:


@NgModule({

  providers: [

    {

      provide: Window,

      useValue: window

    },

  ]

})


export class TestComponent implements OnInit {

  constructor(@Inject(Window) private window: Window)

}

哪个工作正常。


将这种方法用于版本 8 会在编译期间引发警告和错误:


警告:无法解析 TestComponent 的所有参数……


我通过使用单引号解决了它,如下所示:


@NgModule({

  providers: [

    {

      provide: 'Window',

      useValue: window

    },

  ]

})


export class TestComponent implements OnInit {

  constructor(@Inject('Window') private window: Window)

}

两个版本有什么区别?

导致这个问题的 Angular 8 和 9 有什么区别?


隔江千里
浏览 407回答 2
2回答

慕妹3242003

为了让您的应用程序与服务器端渲染一起工作,我建议您不仅通过令牌使用窗口,还要以 SSR 友好的方式创建此令牌,完全不引用window。Angular 具有DOCUMENT用于访问document. 这是我为我的项目想出的window通过令牌使用的内容:import {DOCUMENT} from '@angular/common';import {inject, InjectionToken} from '@angular/core';export const WINDOW = new InjectionToken<Window>(&nbsp; &nbsp; 'An abstraction over global window object',&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; factory: () => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const {defaultView} = inject(DOCUMENT);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!defaultView) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new Error('Window is not available');&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return defaultView;&nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; },);编辑:由于这是人们经常需要的东西,我们使用这种技术创建了一个带有全局对象注入令牌的小型开源库,因此您可以使用它:https://github.com/ng-web-apis/common它有一个姊妹库,用于在 Angular Universal 中与 SSR 一起使用的模拟:https://github.com/ng-web-apis/universal总体而言,请查看我们的 Angular 原生 API 中心:https://ng-web-apis.github.io/

不负相思意

考虑ValueProvider接口:export declare interface ValueProvider extends ValueSansProvider {&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; provide: any;&nbsp; &nbsp; /**&nbsp; &nbsp; &nbsp;* When true, injector returns an array of instances. This is useful to allow multiple&nbsp; &nbsp; &nbsp;* providers spread across many files to provide configuration information to a common token.&nbsp; &nbsp; &nbsp;*/&nbsp; &nbsp; multi?: boolean;}该provide属性为 类型any。这意味着任何对象(包括Window构造函数)都可以进入其中。对象实际上并不重要,只有引用才重要,以确定应该使用哪个提供者在构造函数中注入参数。使用本机构Window造函数作为注入令牌不应被视为一种好的做法。它在编译时失败,因为它Window在运行时存在于浏览器环境中,它也作为 TypeScript 存在,declare但 Angular 8 编译器无法进行静态代码分析来关联Window提供者和Window构造函数中的参数,因为赋值Window已经完成通过浏览器,而不是代码。不知道为什么它在 Angular 9 中有效,但......您应该创建自己的表示依赖项提供程序的注入令牌。此注入令牌应该是:一个专用的字符串(就像你做的那样'Window')一个专用的InjectionToken。例如export const window = new InjectionToken<Window>('window');此外,Angular 代码应该与平台无关(应该可以在浏览器和 Node.js 服务器上执行),因此最好使用返回window或undefined/的工厂null,然后在组件中处理undefined/null情况。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript