【问题标题】:Lazy loading - Providers and modules延迟加载 - 提供程序和模块
【发布时间】:2018-08-30 15:08:18
【问题描述】:

我正在将我的应用程序移至延迟加载。我已经完成了页面、管道和指令,但现在轮到提供程序/服务和其他一些模块了。

这是我的app.module

...
import { FileUploadModule } from "ng2-file-upload";
import { CloudinaryModule } from "@cloudinary/angular-5.x";
import * as cloudinary from "cloudinary-core";
import { ImageUploadProvider } from "../services/image-upload/image-upload";
...
imports: [
 ...
 FileUploadModule,
 CloudinaryModule.forRoot(cloudinary, {
   cloud_name: "cloudName",
   upload_preset: "cloudCode"
  }),
  ...
]
providers: [
 ...
 ImageUploadProvider
  ...
]

现在,这些引用已从此文件中删除。

我的new-recipe 组件需要所有这些。为此,我将其添加到 new-recipe.module:

import { ImageUploadProvider } from "../../services/image-upload/image-upload";
...
providers: [
    ImageUploadProvider
  ]

我还需要什么?我还创建了一个image-upload.module,但不确定这是否正确:

import { NgModule, ModuleWithProviders } from '@angular/core';
import { FileUploadModule } from "ng2-file-upload";
import { CloudinaryModule } from "@cloudinary/angular-5.x";
import * as cloudinary from "cloudinary-core";
import { ImageUploadProvider } from '../services/image-upload/image-upload';

@NgModule({
  imports: [
    FileUploadModule,
    CloudinaryModule.forRoot(cloudinary, {
      cloud_name: "cloudName",
      upload_preset: "cloudId"
    })
  ],
  exports: [
    CloudinaryModule
  ]
})

export class ImageUploadProviderModule {
  static forRoot(): ModuleWithProviders {
    return {
      ngModule: ImageUploadProviderModule,
      providers: [ImageUploadProvider] // <-- is this necessary?
    };
  }
}

我需要在new-recipe.module 中导入这个新模块并删除提供者引用吗?然后如何从new-recipe 中的函数访问 this.imageUploadProvider?

【问题讨论】:

    标签: angular ionic3 lazy-loading


    【解决方案1】:

    假设您正在延迟加载配方模块,并且在您的配方模块中声明了新配方组件,该组件将使用图像 imageUploadProvider 并且此提供程序也将被其他组件使用,这是可能的解决方案:

    • 如果您只需要配方模块内的组件中的服务/提供程序,那么您需要从 app.module 中的提供程序数组中删除服务的导入,像您所做的那样在您的配方模块中导入服务,提供它在它的提供者数组中。在此之后要使用该服务,只需将服务导入您的组件(它们是您的配方模块的一部分),在组件的构造函数中声明该服务,您就可以开始了,对配方模块中的任何其他组件重复相同的步骤他们将收到相同的实例。
    • 现在,如果您想在任何模块的任何组件中使用 imageUploadProvider 并接收相同的实例,那么您必须在根模块中提供它。为此,您只需在根模块(app.module)中导入服务,并像之前在应用程序模块中所做的那样在提供程序数组中声明它:

      import { ImageUploadProvider } from "../../services/image-upload/image-upload"; ... providers: [ ImageUploadProvider ]

    在此之后,您将能够在您想要的任何组件中导入服务并在其构造函数中声明并使用它们。 您不应将此服务导入任何其他模块并在其提供程序数组中提及它,这将创建一个单独的实例。 如果您正确地进行延迟加载并在组件中正确导入和声明服务,那么此解决方案应该可以工作。您还可以在空闲时间阅读有关共享服务的信息。

    【讨论】:

    • If you want to use the imageUploadProvider in any component across any module and receive the same instance then you'll have to provide it in the root module 或为这些孩子创建一个父组件,在我看来这太过分了。有时最好转向非延迟加载方式以避免将来出现意大利面代码
    • 另一个选项可能是提取我需要在这些组件之间共享的部分并创建一个特定的提供程序来共享信息,所以如果我现在需要保存这样的内容:this.imageUploadProvider.image = 'myImage .jpg'` 现在我会这样做 this.imageUploadProvider.saveImage() { // 下一个提供程序加载到 app.module this.sharedInfoProvider.image = 'myImage.jps';这是个好主意吗?
    • 那么在上一条消息之后,当我们在延迟加载的提供程序上导入一个尚未延迟加载的提供程序时会发生什么?我们是要使用前一个实例的 2 个实例,还是只使用通用实例?
    • 因此,如果您要使每个组件都成为父组件的子组件,则必须使用输入或输出装饰器将数据从每个组件传递到另一个组件。这将创建一个严重嵌套的(意大利面条式)代码,并会阻碍关注点的分离和小组件在其他组件之间的重用。如果您的应用程序非常繁重并且具有不同的独立功能,通常会使用延迟加载,那么您可以通过将所需内容保留在应用程序模块中然后根据用户需要加载其他模块来使您的主模块轻量级,基本上使第一次加载速度更快
    • Fr 第二条评论,提取常用功能是服务的主要功能之一。即使要访问其他组件中的变量“this.sharedInfoProvider.image”,无论如何您都必须在其中注入服务,从而重定向到您的第一个问题。对于第三条评论,您不能将一个提供者注入另一个提供者,您可以将它们注入组件(不是您的用例)和模块中。现在,如果您再次将该服务注入到您的延迟加载模块中,您将获得同一服务的另一个实例,除非您使用了根方法angular.io/guide/singleton-services
    【解决方案2】:

    如果您使用的是 Angular 6(可能也在 5 中,但我不这么认为),您可能只想使用:

    @Injectable({
      providedIn: 'root'
    })
    

    我相信这将按需加载服务,而无需在任何提供程序阵列中提供它们,这将使您的生活变得更加轻松。这为整个应用程序提供了一个可用的单例服务。适用于无状态服务。

    如果更适合您,您也可以指定 providedIn: moduleName

    再一次,您不必在模块的 providers 数组中列出服务。

    请参阅https://angular.io/tutorial/toh-pt4 了解更多信息。搜索providedIn

    【讨论】:

    • 我正在使用 Angular 5。我看了一下,但它只能从 Angular 6 获得。不介意升级,但我使用 Angular 和 Ionic 3。我需要等到 Ionic 4角的版本。与此同时,我需要找到一种不同的方法
    • 目前我可以在@Component 中使用provider: [],但它不起作用。显然它会丢失不同页面之间的信息(除此之外我没有收到任何错误)
    • 您可以使用ngrx并将您的数据存储在那里,然后您的服务可以从ngrx存储中检索数据,ngrx存储数据只会在页面刷新时丢失,但是,您可能需要做更多的工作'现在不需要
    • 这不是我想要的。我不仅需要提供者和服务来存储数据。我也有端点和更多类似的东西
    • ngrx 效果允许调用端点,并且基本上可以执行任何您想要检索数据以存储在存储中的代码,但是,就像我说的那样 - 就您的身份而言,可能会偏离正题努力实现
    猜你喜欢
    • 2020-07-08
    • 2017-07-24
    • 2017-12-04
    • 2018-05-22
    • 2018-03-24
    • 2017-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多