與用戶交互的動態清單列表
以我之前寫的一個清單列表頁面作爲例子(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()”屬性:
<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>