与用户交互的动态清单列表
以我之前写的一个清单列表页面作为例子(MVC模式的清单列表效果),优化前代码如下:
<!DOCTYPE html>
<html ng-app="todoApp"> <head> <meta charset="UTF-8"> <title>TO DO List</title> <link href="./bootstrap/css/bootstrap.css" rel="stylesheet"/> <link href="./bootstrap/css/bootstrap-theme.css" rel="stylesheet"/> <script src="./angularJs/angular.js"></script> <script> var model = { user:"Yimi", items:[{action:"练车",done:true}, {action:"看课外书",done:false}] }; var todoApp = angular.module("todoApp",[]); todoApp.controller("ToDoCtrl",function($scope){ //以$开头的变量名表示AngularJS的内置特性 $scope.todo = model; }); </script> </head> <body ng-controller="ToDoCtrl"> <div class="page-header"> <h1>{{todo.user}}'s TO DO List</h1> <span class="label label-default">{{todo.items.length}}</span> </div> <div class="panel"> <div class="input-group"> <input class="form-control"/> <span class="input-group-btn"> <button class="btn btn-default">Add</button> </span> </div> <table class="table table-striped"> <thead> <tr> <th>Description</th> <th>Done</th> </tr> </thead> <tbody> <tr ng-repeat="item in todo.items"> <td>{{item.action}}</td> <td>{{item.done}}</td> </tr> </tbody> </table> </div> </body> </html>
效果如下:
优化过程
1.使复选框状态与布尔值同步(双向模型绑定)
想要为Done属性添加复选框,并与true/false的值同步,即达到以下效果:
点击复现框会使右侧true/false的值同步变化。
只需要为复选框checkbox指定为与true/false同样的ng-model模型属性:
......
<tbody>
<tr ng-repeat="item in todo.items"> <td>{{item.action}}</td> <td><input type="checkbox" ng-model="item.done"/></td> <td>{{item.done}}</td> </tr> </tbody> ......
即checkbox和true/false的模型均为”item.done”,只在原基础上加了一句<td><input type="checkbox" ng-model="item.done"/></td>
从而达到双向绑定,同步变化的效果。
2.动态显示待办的事项个数
显示值为false的事项个数,需在控制器todoApp.controller内添加一个计数变量incompleteCount,称为”行为名“。
......
todoApp.controller("ToDoCtrl",function($scope){ //以$开头的变量名表示AngularJS的内置特性 $scope.todo = model; $scope.incompleteCount = function(){ var count = 0; angular.forEach($scope.todo.items,function(item){ if(!item.done){count++;} }); return count; } }); ......
在使用显示待办事项数的标签中调用incompleteCount行为名:
......
<h1>{{todo.user}}'s TO DO List</h1> <!--添加ng-hide="incompleteCount() == 0"使未办事项数为0时不显示此标签--> <span class="label label-default" ng-hide="incompleteCount() == 0">{{incompleteCount()}}</span> ......
效果如下:
因为使用了ng-hide=”incompleteCount() == 0”,所以当无待办事项时隐藏数量标签:
3.根据待办事项数显示不同颜色标签效果
在控制器todoApp.controller中添加逻辑,设置一个根据待办事项数判定标签class属性的$scope.warningLevel行为:
......
todoApp.controller("ToDoCtrl",function($scope){ //以$开头的变量名表示AngularJS的内置特性 ...... cope.warningLevel = function(){ return $scope.incompleteCount() < 2 ? "label-success" : "label-warning"; } }); ......
然后为事项数标签添加ng-class=”warningLevel()”属性:
扫描二维码关注公众号,回复:
495297 查看本文章
<span class="label label-default" ng-hide="incompleteCount() == 0" ng-class="warningLevel()">{{incompleteCount()}}</span>
效果如下:
待办事项数 < 2时
待办事项数 >= 2时
4.响应用户输入
在控制器todoApp.controller中添加逻辑,定义$scope.addNewItem使清单列表具有添加新项的功能:
todoApp.controller("ToDoCtrl",function($scope){ //以$开头的变量名表示AngularJS的内置特性 ...... $scope.addNewItem = function(actionText){ $scope.todo.items.push({action:actionText, done:false}); } });
为输入框与Add按钮双向绑定用户所输入的数据actionText:
<div class="input-group">
<input class="form-control" ng-model="actionText"/> <span class="input-group-btn"> <button class="btn btn-default" ng-click="addNewItem(actionText)">Add</button> </span> </div>
效果如下(为了更美观,顺便把事项数标签向上移了点儿):
完整源码(所调用的css/js文件需自己再添加)
<!DOCTYPE html>
<html ng-app="todoApp"> <head> <meta charset="UTF-8"> <title>TO DO List</title> <link href="./bootstrap/css/bootstrap.css" rel="stylesheet"/> <link href="./bootstrap/css/bootstrap-theme.css" rel="stylesheet"/> <script src="./angularJs/angular.js"></script> <script> var model = { user:"Yimi", items:[{action:"练车",done:true}, {action:"看课外书",done:false}] }; var todoApp = angular.module("todoApp",[]); todoApp.controller("ToDoCtrl",function($scope){ //以$开头的变量名表示AngularJS的内置特性 $scope.todo = model; $scope.incompleteCount = function(){ var count = 0; angular.forEach($scope.todo.items,function(item){ if(!item.done){count++;} }); return count; } $scope.warningLevel = function(){ return $scope.incompleteCount() < 2 ? "label-success" : "label-warning"; } $scope.addNewItem = function(actionText){ $scope.todo.items.push({action:actionText, done:false}); } }); </script> </head> <body ng-controller="ToDoCtrl"> <div class="page-header"> <h1>{{todo.user}}'s TO DO List <!--添加ng-hide="incompleteCount() == 0"使未办事项数为0时不显示此标签--> <span class="label label-default" ng-hide="incompleteCount() == 0" ng-class="warningLevel()">{{incompleteCount()}}</span></h1> </div> <div class="panel"> <div class="input-group"> <input class="form-control" ng-model="actionText"/> <span class="input-group-btn"> <button class="btn btn-default" ng-click="addNewItem(actionText)">Add</button> </span> </div> <table class="table table-striped"> <thead> <tr> <th>Description</th> <th>Done</th> </tr> </thead> <tbody> <tr ng-repeat="item in todo.items"> <td>{{item.action}}</td> <td><input type="checkbox" ng-model="item.done"/></td> <td>{{item.done}}</td> </tr> </tbody> </table> </div> </body> </html>