AngularJS学习笔记(2)——与用户交互的动态清单列表

与用户交互的动态清单列表

以我之前写的一个清单列表页面作为例子(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时

待办事项数 >= 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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章