angularjs controllers的使用
更新日期:
这篇主要讲讲control的使用,control顾名思义就是控制器的意思,在传统的mvc框架中,一般用来处理数据再渲染模版。angular这边有点不同。
官方是这么说的:一个控制器是一个javascript的构造函数用来操作angular的$sope对象。
那什么是$sope对象呢?
其实之前我们那个博客小例子已经使用过了。简单来说,angular会为每个control设定一个环境范围,在当前范围里会有个本环境的$sope对象。这个对象上面的值都可以在对应此控制器的模版里面访问到。
controller可以做这两件事:
- 设置$sope对象的初始属性。
- 设置$sope对象的行为。
其实说白了,就是用来设置属性变量,还有方法的。
下面给个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <!doctype html> <html ng-app> <head> <meta charset=utf-8> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js"></script> <script type="text/javascript"> function testCtrl($scope) { $scope.name = 'xxx'; $scope.shout = function(name){ alert(name+" shout!!!"); }; } </script> </head> <body> <div ng-controller="testCtrl"> {{ name }} <div ng-click="shout(name)">点我,叫一下</div> </div> </body> </html> |
注意那个 ng-app,还有ng-click这些都是directive的概念,这边只要知道一个用来启动页面应用,一个用来注册click的事件就好了
可以看到 div通过ng-controller注册了testCtrl这个control,这样在这个div下面,就可以访问到 所有当前control也就是testCtrl的$scope对象的所有值了。
在html下面直接用{{}}来引用属性或者方法名就可以,在directive这些标签里直接使用变量名。
controller的写法
我们上面都是直接全局定义的testCtrl,angularjs实际上不推荐这种写法。
实际上我们应该这么写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!doctype html> <html ng-app="myApp"> <head> <meta charset=utf-8> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js"></script> <script type="text/javascript"> var myapp = angular.module('myApp',[]); myapp.controller('testCtrl', ['$scope', function($scope) { $scope.name = 'xxx'; $scope.shout = function(name){ alert(name+" shout!!!"); }; }]); </script> </head> <body> <div ng-controller="testCtrl"> {{ name }} <div ng-click="shout(name)">点我,叫一下</div> </div> </body> </html> |
主要两个变化:
- 可以看到我们通过
var myapp = angular.module('myApp',[]);
定义了一个模块。然后调用这个模块的controller方法,注册一个叫testCtrl的控制器。这样就将控制器绑在了当前模块下。 - 另外注意
<html ng-app="myApp">
启动应用时,我们要告诉angular启动myApp这个模块。
这边可能有人对
myapp.controller('testCtrl', ['$scope', function($scope) {
这种写法感到奇怪。可以参考之前文章给出的解释,这边不再叙述。
controller的“原型”性。
还记得 javascript里的原型链吗,通过原型链可以一直访问父对象的属性和方法。
这边control的$scope属性也有这个特性。
看下官方的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <!doctype html> <html ng-app="scopeInheritance"> <head> <script src="http://code.angularjs.org/1.2.3/angular.min.js"></script> <script type="text/javascript"> var myApp = angular.module('scopeInheritance', []); myApp.controller('MainCtrl', ['$scope', function($scope){ $scope.timeOfDay = 'morning'; $scope.name = 'Nikki'; }]); myApp.controller('ChildCtrl', ['$scope', function($scope){ $scope.name = 'Mattie'; }]); myApp.controller('GrandChildCtrl', ['$scope', function($scope){ $scope.timeOfDay = 'evening'; //$scope.name = 'Gingerbreak Baby'; }]); </script> <style type="text/css"> div.spicy div { padding: 10px; border: solid 2px blue; } </style> </head> <body> <div ng-app="scopeInheritance" class="spicy"> <div ng-controller="MainCtrl"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="ChildCtrl"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="GrandChildCtrl"> <p>Good {{timeOfDay}}, {{name}}!</p> </div> </div> </div> </div> </body> </html> |
发现没有GrandChildCtrl是ChildCtrl的字标签,本身自己的$scope对象没有name属性,他就会一个个的向上寻找,找到ChildCtrl的属性显示。
每个页面会有个根环境的$scope对象。具体的这边的层级关系为:
GrandChildCtrl scope =》ChildCtrl scope =》 MainCtrl scope =》 root scope
结语
controller基本就介绍完了。实际上controller一般都是跟路由配合,不同的路由会调用不同的controll,这需要后面的service的知识,这个以后会再介绍。