AngularJS 的库里面有很多东西,但本文中我只想专注于小的,针对特定主题的库,我相信通过它们能对Angular有一个较好的介绍. 理解这篇文章并不需要你有任何Angular相关的,甚至是JavaScript的经验。希望你能从本文中看到一些使用Angular的好处,并乐于动手尝试.
背景
我使用Angular有一段时间了,而在学习Angular的时候,我也喜欢构建一些样例,所以当我一开始深入进去的时候,对于模块或者JavaScript的设计模式,我也没有多想,那样对保持代码组织和条理性有帮助. 那就是所有的重点:保持代码的组织和条理性. 因此,现在我回过头来,创建了这个极其小巧的样例,以展示使用模块可以有多简单. 一路走来,我希望它能够成为一篇好的对Angular的介绍.
(大多数)文章在阐述模式时的问题
大多数时候人们都会尝试去在读者知道模式是啥概念之前就开始阐述一个模式,而这基本上误导了每一个人. 这里要努力使得本文尽量简单,让我们首先来看一看这个问题吧。哪个问题呢?就是有关默认会在全局内存空间被创建的所有东西的Javascript的问题.
下面就是我所说的意思.
JavaScript 默认的全局问题
设想你的HTML中有下面这样一段脚本.
<script> var isDoingWork = false; </script>
范围?
你清楚这个变量的范围么?
是的,它是全局的。这个布尔值实际上被添加到了浏览器的全局窗口对象中.
把它设置到Action中
这里你可以看到它在Action中是怎样的.
下载本文的代码样例.
在你的浏览器中打开 modulePattern.htm .
打开浏览器开发工具 -- F12(Chrome, IE) or Ctrl-Shift-I (Opera) -- (那样就可以看见控制台了)
在浏览器工具控制台下,输入: isDoingWork,然后回车<ENTER>
你会看到输出的值为false.
现在输入 : isDoingWork = true,然后回车<ENTER>
如此下载的值就为true了. 你已经改变了这个值.
你可以看到这个值已经通过输入doingwindow.isDoingWork = true然后回车<ENTER>,被添加到了全局窗口对象之中.
这可能会造成一些名字冲突,也会导致一些严重的bug. 这也许对你而言有点杞人忧天了,是不? 但是请设想你是决定要去实现某一个新的JS库,它每分每秒都可以被创建出来. 假设你发现了这个叫做 Panacea.js 的很棒的库,它将解决你所有的问题.
因此你向下面这样在你的页面中引用了它:
<script src="https://www.jb51.net/panacea.js"></script>
如此简单,你就已经解决之前你遇到的所有问题. 然而,因为它是一个庞大的库,而你只想要解决方法,却不回去深挖这个庞大(几千行代码)源文件里的每一行代码. 而深埋在 Panacea.js 里面某个角落的确实下面这样的代码:
var isDoingWork = false; setInterval(function(){isDoingWork = !isDoingWork;}, 3000);
这代码真是酷,你知道吗?
每个3秒,它都会将这个布尔值设置成相对的值。啊!
自己动手看看
如果你想要自己动手验证下这个东西,你可以做下面这几步:
下载本文的样例代码.
在你的浏览器中打开 modulePattern2.htm .
打开浏览器开发工具 -- F12(Chrome, IE) 或者 Ctrl-Shift-I (Opera) -- (这样你就可以看到控制台了)
在浏览器开发工具的控制台下,输入 : isDoingWork 然后回车<ENTER>
将第4步多重复几次,你将会发现isDoingWork的值会每个大约3秒钟变化一次.
那这是不是很棒呢?
我的第一个观点 : 模块模式是很有用的
我需要为此做出解释,为了要向你展示为什么 JavaScript 的模块模式是很有用的. 我得想你展示 JavaScript 的模块模式,那样我就可以告诉你它是如何在AngularJS中被使用或实现的了.
模块模式:封装
如此,实际就是,模块模式基本上就是封装了. 封装听起来很熟悉,如果你有点面向对象编程经历的话 -- 而我也希望你能有点这个经验. 封装是面向对象编程的三原则之一。封装的另外一个说法就是数据隐藏。在经典的面向对象编程中——它不同于JavaScript所依赖的原型化OOP -- 数据隐藏是构建一个类模板的内在组成部分.