服务、指令和模块之间有什么区别?

157
我已经阅读了很多文档,但是越来越困惑了。 基本上我搞不清楚 `服务(service)`、`指令(directive)` 和 `模块(module)` 之间的区别。
我看到很多自定义组件。有时它们使用指令,有时使用服务。一切都始于模块。可以举个例子解释一下这三种类型之间的区别吗?
2个回答

239

根据我的个人笔记(主要是从文档、Google组帖子和SO帖子中提取的片段):

模块

  • 提供一种命名空间/分组服务、指令、过滤器、配置信息和初始化代码的方式
  • 有助于避免全局变量
  • 用于配置$injector,允许在其他地方注入由模块定义的内容(或整个模块本身)(依赖注入)
  • Angular模块与CommonJS或Require.js无关。与AMD或Require.js模块相反,Angular模块不尝试解决脚本加载顺序或延迟脚本获取的问题。这些目标是正交的,并且两种模块系统可以并存并实现它们的目标(因此文档声称)。

服务

  • 是单例的,即每个定义的服务只有一个实例。作为单例,它们不受范围的影响,因此可以被多个视图/控制器/指令/其他服务访问(共享)
  • 当以下情况之一发生时,可以(并且可能应该)创建自定义服务:
    • 两个或多个事物需要访问相同的数据(不要使用根作用域),或者您只是想整洁地封装您的数据
    • 您想封装与Web服务器的交互(在您的服务中扩展$resource或$http)
  • 内置服务以“$”开头。
  • 使用服务需要在依赖项上执行依赖项注入(例如,在控制器、另一个服务或指令上)。

指令(下面的一些项目本质上说相同的事情,但我发现有时稍微不同的措辞会很有帮助)

  • 负责在模型状态更改时更新DOM
  • 扩展HTML语法 = 教会HTML新技巧。
    Angular内置了一组指令(例如ng-*),对于构建Web应用程序非常有用,但您可以添加自己的指令,以便将HTML转换为声明式特定领域语言(DSL)。例如,Angular首页演示“创建组件”中的<tabs>和<pane>元素。
    • 不明显的内置指令(因为它们不以"ng"开头):a、form、input、script、select、textarea。在Angular下,这些都比正常情况下做得更多!
  • 指令允许您"组件化HTML"。 指令通常比ng-include好。例如,当你开始编写大量主要与数据绑定相关的HTML时,将该HTML重构为(可重用的)指令。
  • Angular编译器允许您将行为附加到任何HTML元素或属性,并甚至创建具有自定义行为的新HTML元素或属性。Angular将这些行为扩展称为指令
    • 归根结底,指令只是一个函数,当Angular编译器在DOM中遇到它时执行该函数。
  • 指令是由属性、元素名称、类名称或注释中的名称触发的行为或DOM转换。指令是应在HTML编译过程中遇到特定的HTML结构时触发的行为。指令可以放置在元素名称、属性、类名称以及注释中。
    • 大多数指令仅限于属性。例如,DoubleClick仅使用自定义属性指令。
  • 另请参见什么是AngularJS指令?
  • 在模块中定义和组合Angular事物(依赖注入等)。
    在服务中共享数据并包装Web服务器交互。
    在指令中扩展HTML和进行DOM操作。
    并使控制器尽可能"薄"。


    1
    @Mark Rajcok - 很好的回答,我已经给了你+1,但更详细地澄清模块下的第3项将是很好的,即“配置$injector”。人们了解注入服务,但这与模块有什么关系? - whitneyland
    2
    @LeeWhitney,请参考http://docs.angularjs.org/guide/module#dependencies:“模块可以将其他模块列为它们的依赖项。依赖于一个模块意味着需要在加载要求模块之前加载所需模块。换句话说,所需模块的配置块在要求模块的配置块之前执行。” - Mark Rajcok
    @MarkRajcok 的链接现在已经失效。 - Michael Smith

    125

    将模块视为连接指令、服务、常量等多个其他项的位置。这些模块可以注入到其他模块中,使您能够高度重复使用。

    编写Angular应用程序时,您将拥有一个顶层模块,它是您的应用程序代码(不包括模板)。

    服务主要是在控制器之间通信的一种方式,但您可以在一个服务中注入另一个服务。通常将服务用作访问数据存储库的方式,人们会封装Angular API(如ngResource)。此技术很有用,因为它使测试(特别是模拟)非常容易。您还可以为其他事情创建服务,例如身份验证、日志记录等。

    指令用于创建小部件或包装现有内容,例如jQuery插件。包装现有插件可能有挑战性,您之所以这样做是为了在插件和Angular之间建立双向数据绑定。如果您不需要双向数据绑定,则不需要将其包装。

    指令也是进行DOM操作、捕获DOM事件等的位置。您不应该在控制器或服务中执行与DOM相关的操作。创建指令可能变得非常复杂。我个人认为,首先查看API是否可以实现您要寻找的内容,或者向Angular的Google Group寻求建议。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接