AngularJS--控制器(Controller)
2015-10-20 11:36
579 查看
点击查看AngularJS系列目录
转载请注明出处:http://www.cnblogs.com/leosx/
当一个控制器通过ng-controller指令连接到DOM上,Angular将实例化一个新的控制器对象,然后调用指定的控制器的构造函数。一个新的子作用范围(scope)将被创建,并作为一种可注入的参数传递给控制器的构造函数为
如果控制器使用
使用
1.初始化
2.为
错误的使用方式:
1.操作DOM -- 控制器中应该只包含业务逻辑。把业务逻辑放到控制器中,可以显著提高可测试性。Angualr大多数情况下使用数据绑定和封装指令来实现手动DOM操作。而不是直接在
2.格式输入 -- 应该使用Angular的表单控件,而不是用原生的表单控件。
3.filter过滤器 -- 应该使用Angular的filter来代替原生的过滤器。
4.跨控制器共享代码或状态 -- 应该使用Angular的服务来代替。
5.管理其他组件的生命周期(例如,创建服务实例)。
通常情况下,当你创建一个应用程序,你都会需要初始化angular的
下面的例子演示如何创建一个GreetingController,并且向
我们为我们的引用程序创建了一个AngularJS模块 – myApp .然后我们使用模块的
在这里,我们已经使用了内嵌的注入器明确指定了由Angualr提供的$scope服务的依赖。查看依赖注入的指南,了解更多信息。
我们使用
在
为了在视图中对事件作出反应或执行计算,我们必须要让
下面的示例向一个控制器的$scope添加一个方法来实现翻倍:
一旦controller被附加到了DOM上,那么这个
正如本指南的概念部分所提到的,任何对象(或原函数)分配到的作用域范围$scope成为模块module的一个属性。任何被附加到
保持控制器干净单一的方法就是把那些和不属于这个控制器的东西放到一个服务中去。然后通过在控制器中依赖注入这个服务,然后去使用服务所提供的方法。将会在本指南的依赖注入和服务节中讨论。
简单例子
文件一:index.html
文件二:app.js
效果图(自己去实现一下看看效果):
来一个例子看看吧!
第一个文件:index.html
第二个文件:app.css
第三个文件:app.js
效果图如下:
请注意我们是如何将
1、root scope(每一个module都会有一个$rootscope)
2、
3、
4、
继承方法和继承属性是一样的。所以,上面的那些属性也可以换成一个返回字符串的方法,都是可以的。
控制器的定义:
控制器的测试:
如果你需要测试嵌套的控制器,你必须按照DOM结构层次去逐一创建对应的controller:
转载请注明出处:http://www.cnblogs.com/leosx/
理解控制器
在AngularJS的控制器中,构造函数会有Scope参数。当一个控制器通过ng-controller指令连接到DOM上,Angular将实例化一个新的控制器对象,然后调用指定的控制器的构造函数。一个新的子作用范围(scope)将被创建,并作为一种可注入的参数传递给控制器的构造函数为
$scope。
如果控制器使用
controller as语法附加到DOM上,那么控制器实例将被分配给新的
$scope范围。并且多了一个和as同名的属性,然后把自己指向这个属性,就方便我们访问了。
使用
controller:
1.初始化
$scope对象。
2.为
$scope对象附加行为。
错误的使用方式:
1.操作DOM -- 控制器中应该只包含业务逻辑。把业务逻辑放到控制器中,可以显著提高可测试性。Angualr大多数情况下使用数据绑定和封装指令来实现手动DOM操作。而不是直接在
controller里面操作DOM。
2.格式输入 -- 应该使用Angular的表单控件,而不是用原生的表单控件。
3.filter过滤器 -- 应该使用Angular的filter来代替原生的过滤器。
4.跨控制器共享代码或状态 -- 应该使用Angular的服务来代替。
5.管理其他组件的生命周期(例如,创建服务实例)。
$scope
对象的初始化
通常情况下,当你创建一个应用程序,你都会需要初始化angular的$scope。通常情况下,我们在初始化
$scope的时候,都是为
$scope附加一些属性或者方法。该属性包含视图所使用的模型(由视图中提出的模型)。所有
$scope上的属性,在controller中注册的模板的DOM控件都是可以访问的。
下面的例子演示如何创建一个GreetingController,并且向
$scope作用域范围中增加了一个问候语属性:
var myApp = angular.module('myApp',[]); myApp.controller('GreetingController', ['$scope', function($scope) { $scope.greeting = 'Hola!'; }]);
我们为我们的引用程序创建了一个AngularJS模块 – myApp .然后我们使用模块的
.controller()方法将控制器的构造函数模块中去。
在这里,我们已经使用了内嵌的注入器明确指定了由Angualr提供的$scope服务的依赖。查看依赖注入的指南,了解更多信息。
我们使用
ng-controller指令将controller绑定到DOM上。
greeting属性会被绑定到我们到模板上去:
<div ng-controller="GreetingController"> {{ greeting }} </div>
在$scope
上增加一个行为
为了在视图中对事件作出反应或执行计算,我们必须要让$scope提供响应的功能/行为。通常,我们都是附加一个方法来提供这些功能的。附加之后,这些方法就可以被 模板/视图 调用。
下面的示例向一个控制器的$scope添加一个方法来实现翻倍:
var myApp = angular.module('myApp',[]); myApp.controller('DoubleController', ['$scope', function($scope) { $scope.double = function(value) { return value * 2; }; }]);
一旦controller被附加到了DOM上,那么这个
double方法就可以在Angularjs的模板中被调用了。
<div ng-controller="DoubleController"> Two times <input ng-model="num"> equals {{ double(num) }} </div>
正如本指南的概念部分所提到的,任何对象(或原函数)分配到的作用域范围$scope成为模块module的一个属性。任何被附加到
$scope上到属性或者方法,对于view或者模板(template)都是可以访问到的。并且可以通过表达式或者ng-事件来调用(例如:ngClick)。
正确的使用controller
一般情况下,一个控制器不应该试图做太多操作。它应只该包含单个视图所需的业务逻辑。保持控制器干净单一的方法就是把那些和不属于这个控制器的东西放到一个服务中去。然后通过在控制器中依赖注入这个服务,然后去使用服务所提供的方法。将会在本指南的依赖注入和服务节中讨论。
简单例子
文件一:index.html
<div ng-controller="SpicyController"> <button ng-click="chiliSpicy()">Chili</button> <button ng-click="jalapenoSpicy()">Jalapeño</button> <p>The food is {{spice}} spicy!</p> </div>
文件二:app.js
var myApp = angular.module('spicyApp1', []); myApp.controller('SpicyController', ['$scope', function($scope) { $scope.spice = 'very'; $scope.chiliSpicy = function() { $scope.spice = 'chili'; }; $scope.jalapenoSpicy = function() { $scope.spice = 'jalapeño'; }; }]);
效果图(自己去实现一下看看效果):
多层次的Scope示例
现在我们来初步看一下将controller多层次的绑定在DOM上。当ng-controller指令创建了一个新的$scope,我们要知道,这个
$scope是继承自上级
$scope而来的(每个module都会有一个
$rootScope,第一级
controller的
$scope将会继承自这个
$rootscope)。既然是继承,那么子集
controller的
$scope就会包含了上级
controller的
$scope所有的属性和方法!关于更多的$scope相关的,请查阅相关章节。
来一个例子看看吧!
第一个文件:index.html
<div class="spicy"> <div ng-controller="MainController"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="ChildController"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="GrandChildController"> <p>Good {{timeOfDay}}, {{name}}!</p> </div> </div> </div> </div>
第二个文件:app.css
div.spicy div { padding: 10px; border: solid 2px blue; }
第三个文件:app.js
var myApp = angular.module('scopeInheritance', []); myApp.controller('MainController', ['$scope', function($scope) { $scope.timeOfDay = 'morning'; $scope.name = 'Nikki'; }]); myApp.controller('ChildController', ['$scope', function($scope) { $scope.name = 'Mattie'; }]); myApp.controller('GrandChildController', ['$scope', function($scope) { $scope.timeOfDay = 'evening'; $scope.name = 'Gingerbread Baby'; }]);
效果图如下:
请注意我们是如何将
ng-controller指令嵌套在我们的模板当中的。上面的例子中,总共产生了四个scope。
1、root scope(每一个module都会有一个$rootscope)
2、
MainController的scope,其中包含了
timeOfDay和
name属性。
3、
ChildController的scope,它继承了上一级的
timeOfDay属性,并且重写了上一级的
name属性。
4、
GrandChildController的scope,它重写了所有上级的
timeOfDay和
name属性。
继承方法和继承属性是一样的。所以,上面的那些属性也可以换成一个返回字符串的方法,都是可以的。
测试控制器(controller)
虽然有许多方法来测试一个控制器,但是推荐如下图所示,注入$rootScope和$controller的方式来测试:控制器的定义:
var myApp = angular.module('myApp',[]); myApp.controller('MyController', function($scope) { $scope.spices = [{"name":"pasilla", "spiciness":"mild"}, {"name":"jalapeno", "spiciness":"hot hot hot!"}, {"name":"habanero", "spiciness":"LAVA HOT!!"}]; $scope.spice = "habanero"; });
控制器的测试:
describe('myController function', function() { describe('myController', function() { var $scope; beforeEach(module('myApp')); beforeEach(inject(function($rootScope, $controller) { $scope = $rootScope.$new(); $controller('MyController', {$scope: $scope}); })); it('should create "spices" model with 3 spices', function() { expect($scope.spices.length).toBe(3); }); it('should set the default value of spice', function() { expect($scope.spice).toBe('habanero'); }); }); });
如果你需要测试嵌套的控制器,你必须按照DOM结构层次去逐一创建对应的controller:
describe('state', function() { var mainScope, childScope, grandChildScope; beforeEach(module('myApp')); beforeEach(inject(function($rootScope, $controller) { mainScope = $rootScope.$new(); $controller('MainController', {$scope: mainScope}); childScope = mainScope.$new(); $controller('ChildController', {$scope: childScope}); grandChildScope = childScope.$new(); $controller('GrandChildController', {$scope: grandChildScope}); })); it('should have over and selected', function() { expect(mainScope.timeOfDay).toBe('morning'); expect(mainScope.name).toBe('Nikki'); expect(childScope.timeOfDay).toBe('morning'); expect(childScope.name).toBe('Mattie'); expect(grandChildScope.timeOfDay).toBe('evening'); expect(grandChildScope.name).toBe('Gingerbread Baby'); }); });
相关文章推荐
- [AngularJS + Unit Testing] Testing Directive's controller with bindToController, controllerAs and isolate scope
- angular之ngSanitize
- angular之$eval
- windows中安装yeoman构建angularJs项目
- bug记录:angularJS页面没法正常加载
- 转载:Angular的filter总结
- 转载:Think in AngularJS:对比jQuery和AngularJS的不同思维模式(大漠穷秋)
- 图片上传(angular)
- AngularJS 异常处理
- angular指令心得(ng-model)
- Meteor+Angular实现轻论坛——Meteor和Angular基础介绍
- Cordova插件之友盟统计
- AngularJs之指令
- angularjs 控制style
- AngularJS1.3一些技巧
- AngularJS-Controller的使用-读书笔记
- AngularJS 实现按需异步加载实例代码
- 浅析angular
- AngularJS 实现按需异步加载实例代码
- angular controller 依赖声明