为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

隔江千里 2022-01-01 20:07:40
我有两个使用这些版本的 Angular 项目:9.0.0-next.68.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 有什么区别?
查看完整描述

2 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

为了让您的应用程序与服务器端渲染一起工作,我建议您不仅通过令牌使用窗口,还要以 SSR 友好的方式创建此令牌,完全不引用window。Angular 具有DOCUMENT用于访问document. 这是我为我的项目想出的window通过令牌使用的内容:


import {DOCUMENT} from '@angular/common';

import {inject, InjectionToken} from '@angular/core';


export const WINDOW = new InjectionToken<Window>(

    'An abstraction over global window object',

    {

        factory: () => {

            const {defaultView} = inject(DOCUMENT);


            if (!defaultView) {

                throw new Error('Window is not available');

            }


            return defaultView;

        },

    },

);

编辑:由于这是人们经常需要的东西,我们使用这种技术创建了一个带有全局对象注入令牌的小型开源库,因此您可以使用它:


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/


查看完整回答
反对 回复 2022-01-01
?
不负相思意

TA贡献1777条经验 获得超10个赞

考虑ValueProvider接口:


export declare interface ValueProvider extends ValueSansProvider {

    /**

     * An injection token. Typically an instance of `Type` or `InjectionToken`, but can be `any`.

     */

    provide: any;

    /**

     * When true, injector returns an array of instances. This is useful to allow multiple

     * providers spread across many files to provide configuration information to a common token.

     */

    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情况。


查看完整回答
反对 回复 2022-01-01
  • 2 回答
  • 0 关注
  • 358 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信