149

我很好奇 AngularJS 中的装饰器到底是什么。除了AngularJS 文档中的简介和youtube 视频中的简短(尽管很有趣)提及外,没有太多关于装饰器的在线信息。

正如 Angular 的人所说,装饰器是:

服务的装饰,允许装饰器拦截服务实例的创建。返回的实例可以是原始实例,也可以是委托给原始实例的新实例。

我真的不知道那是什么意思,我不确定你为什么要将这个逻辑与服务本身分开。例如,如果我想在不同的条件下返回不同的东西,我只需将不同的参数传递给相关函数或使用另一个共享该私有状态的函数。

我仍然是一个 AngularJS 菜鸟,所以我确信这只是我养成的无知和/或坏习惯。

4

5 回答 5

219

一个很好的用例$provide.decorator是当您需要对模块所依赖的某些第三方/上游服务进行较小的“调整”,同时保持服务完好无损(因为您不是服务的所有者/维护者)。是关于 plunkr 的演示。

于 2013-04-18T08:54:47.970 回答
66

装饰器允许我们分离横切关注点并允许服务保留单一职责原则,而无需担心“基础设施”代码。

装饰器的实际用途:

  • 缓存:如果我们有一个服务可能会进行昂贵的 HTTP 调用,我们可以将服务包装在一个缓存装饰器中,该装饰器在进行外部调用之前检查本地存储。
  • 调试/跟踪:根据您的开发/生产配置进行切换,使用调试或跟踪包装器装饰您的服务。
  • 节流:将频繁触发的调用包装在一个去抖动的包装器中。例如,允许我们轻松地与速率受限的服务进行交互。

在所有这些情况下,我们将服务中的代码限制为其主要职责。

于 2013-04-18T13:52:53.590 回答
10

decorator可以拦截由创建的服务实例factory, service, value, provider,并提供选项来更改一些instance(service)否则不可配置的/带有选项的选项。

它还可以提供用于测试目的的模拟实例,例如$http.

于 2013-07-21T04:59:08.580 回答
4

简单来说,我们可以说它就像一个扩展方法。对于前。我们有一个类,它有两个方法,在运行时我们想在其中添加更多方法,然后我们使用装饰器。

我们不能将 $provide.decorator 与常量一起使用,因为我们无法更改它们正在提升只读属性的常量。

于 2015-06-12T15:42:36.550 回答
1

简而言之,装饰器可以描述如下:-

装饰器函数拦截服务的创建,允许它覆盖或修改服务的行为。

$provide通过角度使用服务并修改或替换另一个服务的实现

$provide.decorator('service to decorate',['$delegate', function($delegate) {
  // $delegate - The original service instance, 
  //             which can be replaced, monkey patched, 
  //             configured, decorated or delegated to. 
  //             ie here what is there in the 'service to decorate'

  //   This function will be invoked, 
  //   when the service needs to be provided 
  //   and should return the decorated service instance.
  return $delegate;
}]);

例子:

$provide.decorator('$log', ['$delegate', function($delegate) {
  // This will change implementation of log.war to log.error
  $delegate.warn = $delegate.error; 
  return $delegate;
}]);

应用

除了@JBland 答案。

  • 应用程序范围的区域设置:-

    你可以在这里找到一个例子

  • 通过角度服务更改服务的默认行为和现有实现:-

    你可以在这里找到一个例子

  • 一个函数在不同环境中的切换行为。

于 2017-12-19T06:23:52.010 回答