Angularjs之controller 和filter(四)
Controller组件(http://www.angularjs.cn/A00C)
在AngularJS中,控制器是一个Javascript函数(类型/类),用来增强除了根作用域以外的作用域实例的。当你或者AngularJS本身通过scope.$new俩创建一个新的子作用域对象时,有一个选项能让你将它当做参数传递给控制器。这能使AngularjS将控制器和这个作用域联系起来,增强作用域的行为。
控制器用于:
- 设置好作用域对象的初始状态。
- 给作用域对象增加行为。
正确使用控制器:
保持控制器职责单一的最常见做法是将那些不属于控制器的工作抽离到服务中,然后通过依赖注入在控制器中使用这些服务。这在依赖注入服务的章节中会详细讨论。
不要用控制器干下面的事情:
- 控制器应该只关心业务逻辑。DOM操作(表现层逻辑)通常会把测试弄得很难。将任何表现层逻辑放到控制器中都会显著地增加对业务逻辑的测试难度。AngularJS提供dev_guide.templates.databinding用来自动进行DOM操作。如果你需要手动操作DOM,将表现层的逻辑抽离到指令中。
- 对输入格式化 — 你应该用AngularJS的表单控制来实现格式化。.
- 对输出格式化 — 该用AngularJS的过滤器实现。.
- 在控制器中运行无状态或者有状态但在控制器中共享的代码 — 该用服务来实现.
- 实例化组件或者控制其它组件的生命周期(比如创建一个服务的实例).
控制器构造函数和方法的例子
为了阐述AngularJS的控制器组件的运行原理,让我们来创建一个拥有下面这些组件的小应用:
- 一个有两个按钮和一条消息的模板
- 一个叫spice的字符串模型。
- 一个拥有两个方法的控制器。方法是用来设置spice的值得。
模板中的消息包含了一个对spice模型的绑定,它初始的字符串是“very”。这个spice模型会被设置成 chili 或者 jalapeno,这取决于哪个按钮会被点击。消息会通过data-binding自动更新。
一个 spice 控制器例子(阐述了控制器的特点:1给对象初始化2给对象添加行为)
<body ng-controller="SpicyCtrl">
<button ng-click="chiliSpicy()">Chili</button>
<button ng-click="jalapenoSpicy()">Jalapeño</button>
<p>The food is {{spice}} spicy!</p>
</body>
function SpicyCtrl($scope) {
$scope.spice = 'very';
$scope.chiliSpicy = function() {
$scope.spice = 'chili';
}
$scope.jalapenoSpicy = function() {
$scope.spice = 'jalapeño';
}
}
例子中有下面这些需要注意:
- ngController指令是用来(隐式地)为模板创建作用域的。并且使用命令中指定的spicyCtrl控制器来增强这个作用域。
- spicyCtrl只是一个纯Javascript函数。使用了驼峰式命名法(可选)命名并以Ctrl或者Controller结尾。
- 对作用域对象赋予一个新的属性会创建或者更新模型。
- 控制器方法能够直接通过赋格作用域对象这个方式创建(如例子中的chiliSpicy方法)。
- 控制器中的所用方法都能在模板中调用(在body元素或者子元素中).
- NB:AngularJS的老版本(1.0RC之前的)能让你用它来替换$scope方法。但是现在不行了。在作用域中定义的方法中,他和$scope是可以互换的(AngularJS将它设置成$scope),那是在你的控制器构造函数中就不行了。
- NB: AngularJS的老版本(1.0RC之前的)自动给作用域对象原型添加方法,现在不会了。所有的方法都必须手动添加到作用域。
- 控制器方法参数的例子
- <body ng-controller="SpicyCtrl">
- <input ng-model="customSpice" value="wasabi">
- <button ng-click="spicy('chili')">Chili</button>
- <button ng-click="spicy(customSpice)">Custom spice</button>
- <p>The food is {{spice}} spicy!</p>
- </body>
- function SpicyCtrl($scope) {
- $scope.spice = 'very';
- $scope.spicy = function(spice) {
- $scope.spice = spice;
- }
- }
- 注意SpicyCtrl控制器只定义了一个叫spicy的方法,它接受一个叫做spice的参数。和这个控制器相关的模板在第一个按钮事件中传递了一个chili常量给控制器方法,在第二个按钮中传递一个模型属性。
Angularjs 过滤器(学习文章:http://www.tuicool.com/articles/ueUZBv)
1.详尽内容看学习文章
2.自定义过滤器
filter的自定义方式也很简单,使用module的filter方法,返回一个函数,该函数接收输入值,并返回处理后的结果。话不多说,我们来写一个看看。比如我需要一个过滤器,它可以返回一个数组中下标为奇数的元素,代码如下:
app.filter('odditems',function(){
return function(inputArray){
var array = [];
for(var i=0;i<inputArray.length;i++){
if(i%2!==0){
array.push(inputArray[i]);//(d) push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。 此例子中将数组下标为基数的值,赋值给空数组array
}
}
return array;
}
});
实例代码:
<!DOCTYPE html> <html ng-app="xmpl"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Controller组件实例学习</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <script src="js/jquery-1.11.3.min.js"></script> <script src="js/bootstrap.min.js"></script> <script src="js/angular.min.js"></script> <script type="text/javascript">var app=angular.module('xmpl',[]);</script> <style type="text/css"> .border{border: 2px solid #ccc; width: 80%; margin: 20px auto;} </style> </head> <body > <div class="border"> <!-- 控制器方法参数的例子 ============================================ --> <h3>1.控制器方法参数的例子</h3> <ul> <li>一个有两个按钮和一条消息的模板</li> <li>一个叫<code class="prettyline">spice</code>的字符串模型。</li> <li>一个拥有两个方法的控制器。方法是用来设置<code class="prettyline">spice</code>的值得。</li> </ul> <div ng-controller="SpicyCtrl"> <input ng-model="customSpice" value="wasabi"> <button ng-click="spicy('chili')">Chili</button> <button ng-click="spicy(customSpice)">Custom spice</button> <p>The food is {{spice}} spicy!</p> </div> <script type="text/javascript"> app.controller('SpicyCtrl',function ($scope) { $scope.spice = 'very'; $scope.spicy = function(spice) { $scope.spice = spice; } }); </script> </div> <!-- 控制器继承示例 =========================================== --> <div class="border"> <h3>2.控制器继承示例,作用域层级</h3> <ul> <li> 根作用域</li> <li>MainCtrl作用域, 它包含了模型timeOfDay和模型name。</li> <li>ChildCtrl作用域,它继承了上层作用域的timeOfDay,复写了name。</li> <li>BabyCtrl作用域,复写了MainCtrl中定义的timeOfDay和ChildCtrl中的name。</li> </ul> <div ng-controller="MainCtrl"> <p>Good {{timeOfDay}}, {{name}}!</p> <div ng-controller="ChildCtrl"> <p>Good {{timeOfDay}}, {{name}}!</p> <p ng-controller="BabyCtrl">Good {{timeOfDay}}, {{name}}!</p> </div> </div> <script type="text/javascript"> app.controller('MainCtrl',function ($scope) { $scope.timeOfDay = 'morning'; $scope.name = 'Nikki'; }); app.controller('ChildCtrl',function ($scope) { $scope.name = 'Mattie'; }); app.controller('BabyCtrl',function ($scope) { $scope.timeOfDay = 'evening'; $scope.name = 'Gingerbreak Baby'; }); </script> </div> <!-- 3.Angularjs 反向输出字符串过滤器 ==================================--> <div class="border"> <h3>3.Angularjs 过滤器</h3> <div ng-controller="Ctrl"> <input ng-model="greeting" type="greeting"><br> No filter: {{greeting}}<br> Reverse: {{greeting|reverse}}<br> Reverse + uppercase: {{greeting|reverse:true}}<br> </div> </div> <script> app.filter('reverse', function() { return function(input, uppercase) { var out = ""; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } // conditional based on optional argument if (uppercase) { out = out.toUpperCase(); } return out; } }); app.controller('Ctrl',function ($scope) { $scope.greeting = 'hello'; }); </script> <!-- 反向输出字符串测试======================== --> <div class="border"> <h3>反向输出字符串测试</h3> <p>reverse 函数的测试 ,运用到charAt()函数:(d)charAt() 方法可返回指定位置的字符,返回的字符是长度为 1 的字符串 (m) stringObject.charAt(index)</p> <p>Input field: <input type="text" id="test3" value="Mickey Mouse"></p> <button id="btn3">设置值</button> <script> $(document).ready(function(){ $("#btn3").click(function(){ var result=reverse($("#test3").val()); $("#test3").val(result); }); }); function reverse(input){ var out=""; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } return out; } </script> </div> </body> </html>