解决 Angular 应用程序中的依赖注入问题

阅读时长 7 分钟读完

Angular 是一个开源的前端框架,它提供了很多功能来帮助开发人员构建可伸缩的现代 Web 应用程序。其中一个功能是依赖注入(Dependency Injection,DI)。通过 DI,我们可以将对象或函数的依赖项注入到其构造函数或方法中,从而实现在不同模块和组件之间共享可重用的代码和逻辑的目的。然而,在 Angular 应用程序中使用 DI 时,可能会遇到一些问题。在本文中,我们将介绍如何解决 Angular 应用程序中的依赖注入问题。

问题描述

首先,让我们了解一下在 Angular 应用程序中遇到的常见 DI 问题。下面是几个例子:

问题 1:找不到提供者(Provider)

当我们在组件或服务中使用某个依赖项时,Angular 将尝试查找供应商(Provider)并注入该依赖项。如果找不到提供者,就会抛出异常。例如,我们定义了以下组件:

-- -------------------- ---- -------
------ - ---------- ------ - ---- ----------------
------ - --------- - ---- ---------------

------------
  --------- ---------------
  --------- ------ --------------- -------
--
------ ----- ----------- -
  ------------------------------ ------- ---------- ---------- --
-

并在服务 MyService 中定义以下代码:

在这种情况下,我们需要将 MyService 添加到 AppModule 中的 providers 数组中,如下所示:

-- -------------------- ---- -------
------ - -------- - ---- ----------------
------ - ------------- - ---- ----------------------------
------ - ----------- - ---- -----------------
------ - --------- - ---- ---------------

-----------
  -------- ----------------
  ------------- --------------
  ---------- ------------
  ---------- -------------
--
------ ----- --------- --

问题 2:无法解析参数

当我们尝试在组件或服务中注入依赖项时,Angular 可能会抛出 “无法解析参数” 的异常。这通常发生在我们尝试在构造函数中注入其他服务的实例时。例如,我们有以下代码:

-- -------------------- ---- -------
------ - ---------- ------ - ---- ----------------
------ - --------- - ---- ---------------

------------
  --------- ---------------
  --------- ------ ------- -------
--
------ ----- ----------- -
  ------------------------------ ------- ---------- ---------- --
  
  ------ --- --------- -
    ------ ------------------------- - - ---- -------------
  -
-

------ - ---------- - ---- ----------------

-------------
------ ----- --------- -
  ------- ----- - ------ -------
  
  ------ ---------- -
    ------ -----------
  -
-

这将导致 Angular 抛出以下异常:

这是因为我们没有将 MyService 添加到 AppModule 中的 providers 数组中,如下所示:

-- -------------------- ---- -------
------ - -------- - ---- ----------------
------ - ------------- - ---- ----------------------------
------ - ----------- - ---- -----------------
------ - --------- - ---- ---------------

-----------
  -------- ----------------
  ------------- --------------
  ---------- ------------
  ---------- -------------
--
------ ----- --------- --

解决方法

为了解决这些 DI 问题,我们可以采取以下措施:

解决方法 1:添加提供者

如上所述,我们需要将所有使用的服务添加到 AppModule 的 providers 数组中,并根据需要使用 @Injectable() 装饰器来标记它们。这将使 Angular 能够正确地解析依赖项并注入它们到组件或服务中。

解决方法 2:使用 Injector

如果我们无法将依赖项添加到 AppModule 中的 providers 数组中,或者我们需要在运行时动态注入依赖项,我们可以使用 Injector 对象。Injector 允许我们在不使用提供者的情况下获取服务的实例,并将实例注入到组件或服务中。例如,我们可以重写上面的 MyComponent 代码来使用 Injector:

-- -------------------- ---- -------
------ - ---------- -------- - ---- ----------------
------ - --------- - ---- ---------------

------------
  --------- ---------------
  --------- ------ ------- -------
--
------ ----- ----------- -
  ------- ---------- ----------
  
  ------------------- --------- --------- --
  
  ------ ---------- -
    -------------- - -----------------------------
  -
  
  ------ --- --------- -
    ------ ------------------------- - - ---- -------------
  -
-

这将使我们无需使用 @Injectable() 装饰器,也可以在使用提供者的情况下获取服务的实例。

解决方法 3:使用 SkipSelf 和 Optional

SkipSelf 和 Optional 装饰器是用于注入依赖项的其他装饰器。SkipSelf 告诉 Angular 忽略组件本身的提供者并查找父级组件的提供者。Optional 告诉 Angular 如果找不到提供者,则不要抛出异常并将依赖项设置为 null。例如,我们可以在 MyComponent 中使用 SkipSelf 和 Optional 装饰器来注入 MyService 并忽略组件自身的提供者:

-- -------------------- ---- -------
------ - ---------- --------- -------- - ---- ----------------
------ - --------- - ---- ---------------

------------
  --------- ---------------
  --------- ------ ------- --------
  ---------- -----------
--
------ ----- ----------- -
  ----------------------- ----------- ------- ---------- ---------- --
  
  ------ --- --------- -
    ------ -------------- - ------------------------- - - ---- ------------ - -------- --- -------
  -
-

这将使我们能够在不添加 MyService 提供程序的情况下获取 MyService 实例。

总结

在本文中,我们介绍了如何解决在 Angular 应用程序中使用 DI 时遇到的常见问题。我们讨论了如何添加提供程序、使用 Injector 对象和使用 SkipSelf 和 Optional 装饰器来注入依赖项。请注意,在实际项目中,我们应该根据实际需求选择适当的解决方案并遵循最佳实践。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64c60ab94908f32798b21deb

纠错
反馈