企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# Angular模块 ## Angular模块 与其他现代语言不同,当前版本的JavaScript(ECMAScript5)并没有内置模块化语法。但是,随着程序规模越来越大,模块化的需求越来越重要,于是出现了require.js等第三方库,试图用库来弥补语言的不足。Angular并不依赖require.js等第三方库,而是自己实现了模块化系统,这个系统的核心就是模块(module)。 所谓模块是指把相关的一组编程元素(如类、函数、变量等)组织到同一个发布包中。这些编程元素之间紧密协作,隐藏实现细节,只通过公开的接口与其他模块合作。模块是一个粒度适中的复用单位,也是最常见的复用形式。比如我们常用的第三方库往往对外公开好几个类,使用者只要关注其公开接口就可以了,不用了解其实现细节,这种第三方库就是一个“模块”。Angular的module也是如此。Angular中的编程元素包括Service、Directive、Filter、Controller等,它们只有通过模块进行“导出”才能供别人使用。 一个程序往往不会只含有一个模块,这些模块需要互相协作,这就导致了模块之间具有依赖关系。 如果你曾经用jQuery写过传统的非MVC前端程序,你会看到的这些代码可能会让你感到惊讶——不再有连篇累牍的DOM操作,不再有混合了业务逻辑和视图逻辑的臃肿代码,不再一听到写测试就闪过“不可能”三个字……“光荣属于MVC!”我们说Angular是个MVW(Model-View-Whatever)风格的框架,而在Angular中扮演Model角色的概念,就是作用域(scope)。在Angular中,scope通过原型继承的方式被组织成了一棵树,它的根节点就是$rootScope,这是Angular在启动时自动创建的,它通常对应于ng-app指令,并且关联到ng-app所在的节点。接下来,Angular会解析ng-app包含的HTML,其中的一些指令,如ng-view、ng-if、ng-repeat等也会创建自己的scope,这些scope都是从$rootScope及其子scope创建出来的,它们的嵌套关系也和这些指令的嵌套关系一致。由于它们使用了原型继承的方式,所以,凡是上级scope拥有的属性,都可以从下级scope中读取,但是当需要对这些继承下来的属性进行写入的时候,问题就来了:写入会导致在下级scope上创建一个同名属性,而不会修改上级scope上的属性。这不是Bug,而是“原型继承”的固有语义,这是用惯了“类继承”的后端程序员需要特别注意的。这种scope树很好的体现了Model之间的嵌套关系,对业务数据的结构是一个很恰当的抽象。scope之所以如此重要,是因为它事实上是Angular解耦业务逻辑层和视图层的关键:Controller操作scope,View则展现scope的内容,传统前端程序中大量复杂的DOM操纵逻辑都被转变成对scope的操作。这种树形结构不但体现在数据的继承关系上,而且体现在消息的冒泡机制上