在NgModule中使用forRoot的目的是什么?
它与AngularJS 1.x中的提供程序相同吗?
它如何在延迟加载中发挥重要作用?
TIA。
它与单身人士有关。角度服务被加载到页面上1次(单例),所有引用都指向此1个实例。
存在一个延迟加载的模块将尝试创建应该是单例的第二个实例的风险,并且forRoot()方法是一种确保应用程序模块/共享模块/和任何延迟加载的模块都使用相同的1个实例(根实例)。
更多信息复制自:Provide core singleton services module in Angular 2
最好的方法是使用提供程序创建模块。请记住,如果您的服务位于共享模块中,您可能会获得多个实例。最好的办法是使用Module.forRoot配置模块。
按照惯例,forRoot静态方法同时提供和配置服务。它需要一个服务配置对象并返回一个ModuleWithProviders。
仅在根应用程序模块AppModule中调用。在任何其他模块中调用它,特别是在延迟加载的模块中,与意图相反,并且可能产生运行时错误。
记得导入结果;不要将它添加到任何其他@NgModule列表。
如果模块同时提供提供者和声明(组件,指令,管道),然后将其加载到子注入器(如路由)中,则会复制提供者实例。提供者的重复会引起问题,因为它们会影响根实例,这可能是单例。因此,Angular提供了一种将提供者从模块中分离出来的方法,以便可以将相同的模块导入到根模块中,而不是提供者的提供者和子模块。
在模块上为Root()(按惯例)创建静态方法。将提供程序放入forRoot方法,如下所示。为了使其更具体,请以RouterModule为例。 RouterModule需要提供Router服务以及RouterOutlet指令。必须由根应用程序模块导入RouterModule,以便应用程序具有路由器,并且应用程序至少具有一个RouterOutlet。它也必须由各个路由组件导入,以便它们可以将RouterOutlet指令放入其子路径的模板中。
如果RouterModule没有forRoot(),则每个路由组件都会实例化一个新的Router实例,这会破坏应用程序,因为只能有一个路由器。因此,RouterModule具有RouterOutlet声明,因此它可以在任何地方使用,但路由器提供程序仅在forRoot()中。结果是根应用程序模块导入RouterModule.forRoot(...)并获取路由器,而所有路由组件导入不包含路由器的RouterModule。
如果您有一个提供提供程序和声明的模块,请使用此模式将它们分开。
有两种方法可以创建路由模块:
RouterModule.forRoot(routes)
创建一个包含路由器指令,路由配置和路由器服务的路由模块
RouterModule.forChild(routes)
创建一个路由模块,包括路由器指令,路由配置,但不包括路由器服务。当您的应用程序具有多个路由模块时,需要RouterModule.forChild()方法。
请记住,路由器服务负责处理应用程序状态和浏览器URL之间的同步。实例化与同一浏览器URL交互的多个路由器服务会导致问题,因此无论我们在应用程序中导入多少路由模块,在我们的应用程序中只有一个路由器服务实例是至关重要的。
当我们导入使用RouterModule.forRoot()创建的路由模块时,Angular将实例化路由器服务。当我们导入使用RouterModule.forChild()创建的路由模块时,Angular将不会实例化路由器服务。
因此,我们只能使用RouterModule.forRoot()一次,并多次使用RouterModule.forChild()来获取其他路由模块。
forRoot()将用于在应用程序的顶部注入提供程序。每次调用Component和指令的实例时,都会创建一个新实例。当您在应用程序的根目录中提及相同内容时(使用forRoot()),将只创建一个实例。
首先,我们需要了解注入提供程序的注意事项与注入组件和指令的区别。当使用@Injectable注释类时,将在调用时仅创建此类的一个实例,并在整个应用程序中共享该实例。为此,我们必须在NgModule中导入类时添加此(forRoot())方法。
希望你现在清楚。