角窗口提供商
你的$窗户在哪里?没问题,使用此提供程序将窗口注入Angular组件。
为什么?
因为我们不想引用全局窗口
由于我们的应用程序可以在Angular Universion中使用,因此可以在Angular Universion中使用,因此避免直接引用全局对象,因此对象直接在我们的角分量中。虽然您可能没有计划使用角度通用,但这使我们能够清理浏览器的本地人窗口
对象进入组件。
这怎么样?
虽然已经有很多解决方案,但已经是间接访问的方法窗口
对象,我发现许多人实际上并不实际执行任何条件验证,即我们的角度应用程序在浏览器的上下文中正在执行,我们将拥有窗口
目的。
这是我觉得我觉得不充分的解决方案的一个例子:
进口{可注射的}从'@ Angular / Core';功能getWindow.():任何{返回窗口;}@可注射的()出口类windowrefservice.{得到本地窗德():任何{返回getWindow.();}}
快速查看这表明我们不检查应用程序是否正在浏览器的上下文中执行。此外,我们可能希望支持测试的上下文,我们可能希望在其中模拟某些属性或方法窗口
目的。
提出解决方案
以下是建议的解决方案,用于创建可扩展方法来注入窗口
进入我们的角分量。我把它放进了一个SRC / app / core / services / window.service.ts文件在我的应用程序中:
进口{isplatformbrowser.}从“@ Angular / Common”;进口{ClassProvider.那FactoryProvider.那注射议步那platform_id.}从'@ Angular / Core';/ *创建一个新的注射令牌,用于将窗口注入组件。* /出口const窗口=新注射议步('windowtoken');/ *定义抽象类以获取对全局窗口对象的引用。* /出口抽象类windowref.{得到本地窗德():窗口|目的{扔新错误('未实现。');}}/ *定义实现抽象类的类并返回本机窗口对象。* /出口类browserwindowref.延伸windowref.{构造函数(){超();}得到本地窗德():窗口|目的{返回窗口;}}/ *创建一个出厂函数返回本机窗口对象。* /出口功能WindowFactory.(browserwindowref.:browserwindowref.那平实践:目的):窗口|目的{如果(isplatformbrowser.(平实践)){返回browserwindowref.。本地窗德;}返回新目的();}/ *为使用browserwindowref类的Windowref令牌创建一个可注射提供程序。* /constBrowserWindowProvider.:ClassProvider.={提供:windowref.那useclass.:browserwindowref.};/ *创建一个可注射的提供程序,它使用WindowFactory函数返回本机窗口对象。* /constWindowProvider.:FactoryProvider.={提供:窗口那uderfactory.:WindowFactory.那DEPS.:[windowref.那platform_id.]};/ *创建一个提供者数组。* /出口constwindow_providers.=[BrowserWindowProvider.那WindowProvider.];
几件事要注意:
- 我有一个
注射议步
这被宣布为窗口
出口。我们将用它来注射窗口
对象进入我们的组件。 - 我定义了一个抽象类
windowref.
有一个配件本地窗德
属性。 - 然后我定义了
browserwindowref.
延长抽象类的课程,实施本地窗德
财产返回全球可用窗口
目的。 - 该
windowfactory()
函数确定应用程序是否在浏览器的上下文中执行使用isplatformbrowser()
功能。现在,如果应用程序未在浏览器的上下文中执行,那么我只是返回一个新的目的
。此部分可扩展,您可以在另一个上下文中返回模拟对象。该函数期望了一个实例browserwindowref.
和平实践
目的。这些依赖项在于WindowProvider.
- 该
BrowserWindowProvider.
是A.ClassProvider.
提供了一个实例browserwindowref.
使用windowref.
注射令牌。 - 该
WindowProvider.
是A.FactoryProvider.
这是用来的WindowFactory.
返回窗口
对象(或EMTPY对象)当窗口
使用注射令牌。 - 最后,我们声明了一系列叫做的提供者
window_providers.
。
要使用此功能,我们需要添加window_providers.
对我们app.module.ts.模块装饰师提供者
数组:
@ngmodule.({宣言:[AppComponent.那]那进口:[浏览器]那提供者:[window_providers.]那引导:[AppComponent.]})出口类appmodule.{}
你也可能有一个调节器
(或许具有不同的名称)是包含应用程序可用的所有服务,拦截器,模型等的模块。如果是这种情况,请进口window_providers.
在该模块中,然后导入到您的模块中appmodule.
。
然后,我们可以使用窗口
注射令牌注射窗口
进入我们的组成部分:
进口{窗口}从“../core/services/window.service”;出口类indexComponent.{构造函数(@注入(窗口)私人的窗口:窗口){安慰。日志(窗口);}}
这是一个示例,显示了window.navigator.useragent.
串: