| 一、前言 |
早已听说AngularJS的大名,并在很久前也编写过些小demo,但是都没有系统学习过。由于,在下个版本项目中用到了AngularJS,so,那就一起再来研究研究呗。
说到,这个AngularJS,其核心就是对HTML标签的增强。
何为HTML标签增强?
其实就是使你能够用标签完成一部分页面逻辑,具体方式就是通过自定义标签、自定义属性等,这些HTML原生没有的标签/属性在ng中有一个名字:指令(directive)。
至于说AngularJS是MVC,亦或MVVM框架?
都不是,它是MVW,最后的W意思就是说whatever,固有些人也称其为MV*。其中含义,以后实践久了,应该就豁然开朗了,至于现在,move on吧。
该篇博客原文地址:http://www.cnblogs.com/giggle/p/5746085.html
| 二、一切从hello world开始 |
啊,苍茫的天涯是我的爱,绵绵的青山脚下花会开,什么样的节奏是最呀最摇摆,什么样的歌声才是最开怀~~~
现在这个年代,人非草木,什么都得有情怀,不然还混不下去了。所以,接下来我们编写个小demo,来抒发我们的抱负。
这个demo要实现的功能很简单,就是在input框中,输入自定义内容,如hello world,间接改变另一显示区域。
前提:如若没有angular.js文件,请点击这里(here)。
实现代码如下:
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app> <input type="text" ng-model="custom"/> <h1>{{custom}}</h1> </body> </html>
效果图:
怎么样,是八是很惊奇,仅仅用了这几行代码,就实现了这个效果,倘若利用原生代码实现,我们还得监听input框,值若改变,取值,将其动态插入h1中。
啧啧啧,相对于AngularJS显得稍稍笨重了许多,所以这也体现了AngularJS的优点,适合数据操作多的应用。
在“前言”中,我们已经提到,AngularJS其核心就是对HTML标签的增强,且内置的Angular指令是以ng-开头的,如上述代码中的ng-app以及ng-model。
--ng-app指令声明所有被其包含的内容都属于angularjs应用
--ng-model指令将内部$scope的属性名绑定到input框中,从而实现双向绑定。
好了,倘若我想给上述input框一个默认值 ’hello world’ 呢?在value=’hello world’?
噗,No。因为我们在body已用ng-app指令表示在body中都属于angular应用啦,so
<input type='text' ng-model='custom' value='hello world'/>
是不起作用滴,不过可以利用angular内置指令ng-init来达到我们想要的效果。
代码如下:
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app> <input type="text" ng-model="custom" ng-init="custom='hello world'"/> <h1>{{custom}}</h1> </body> </html>
除开这种便捷的方法,我们还可以利用控制器来实现同样的效果。
如下:
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app> <input type="text" ng-model="custom" ng-controller="customController"/> <h1>{{custom}}</h1> <script> function customController($scope){ $scope.custom = 'hello world'; } </script> </body> </html>
效果图如下:
尼玛,怎么不是我们想要的效果?!!
细看代码,发现,我们将控制器customController写在input中的,固出现上述状况。
你可能会问,这是为什么呢?-.-小沈阳附体
因为诸如ng-app、ng-controller这些标签,他们都会创建一个作用域,这个作用域呢,又是以html标签来划分的。如<body ng-app>,那么它所创建的作用域($rootScope),就是在body中生效,即</body>止。如上述代码,我们将控制器customController写在input中,那么这个子作用域就是在input中,<h1>标签中的{{custom}}是获取不到的。
好了,了解了原因,我们修改上述代码,如下,将customController控制器放到body中,即可。
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app ng-controller="customController"> <input type="text" ng-model="custom"/> <h1>{{custom}}</h1> <script> function customController($scope){ $scope.custom = 'hello world'; } </script> </body> </html>
完美!
咦,函数customController中参数$scope什么鬼,我们调用时并没有传入呢。这就涉及到Angular的另一核心特效依赖注入,我们现在先不管他内部原理如何实现的,大概过程就是将预定义好的对象名与具体操作绑定,我们使用时,在参数中调用即可,且注入名字必须与预定义的对象一样,不然会报错。另,$scope对象属于Angular内置对象,代表对应的作用域管理对象。
上述代码中,再细细看来,还是不好呢。我们将控制器写在了全局对象中,虽然不影响代码运行,但不易于维护嘛,好在Angular允许我们使用angular.module方法来声明模块。
该方法接收两个参数,第一个是模块的名称,第二个是依赖列表。利用angular.module修改上述代码,得下:
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app='myApp' ng-controller="customController"> <input type="text" ng-model="custom"/> <h1>{{custom}}</h1> <script> var myApp = angular.module('myApp', []); myApp.controller('customController', function($scope){ $scope.custom = 'hello world'; }); </script> </body> </html>
效果图如下:
| 三、scope作用域 |
AngularJS 应用启动并生成视图时,会将根 ng-app 元素与 $rootScope 进行绑定,$rootScope 是所有 $scope 的最上层对象,可以理解为一个 AngularJS 应用中的全局作用域对象,所以为它附加太多逻辑或者变量并不是一个好主意,和污染 Javascript 全局作用域是一样的。通过诸如控制器、指令等这些命令,我们可以创建子作用域,所有的子作用域都通过原型继承而来(指令的孤立作用域除外),也就是说它们都可以访问父级作用域。
好了,我们通过编写个demo感受一番:
<!DOCTYPE html> <head> <meta charset="utf-8"/> <script src="angular.js"></script> </head> <body ng-app='myApp'> rootScope:{{name}} <div ng-controller="outterController"> outter:{{name}} <div ng-controller="innerController"> inner:{{name}} </div> </div> <script> var myApp = angular.module('myApp', []); myApp.run(function($rootScope){ $rootScope.name = 'rootScope'; }).controller('outterController', function($scope, $timeout){ $timeout(function(){ $scope.name = 'outter'; }, 1000); }).controller('innerController', function($scope, $timeout){ $timeout(function(){ $scope.name = 'inner'; }, 2000); }); </script> </body> </html>