app.js部分,首先是路由。这个之前讲过了,链接在这里——
http://www.cnblogs.com/thestudy/p/5661556.html
1 var app = angular.module("myTodo", ['ngRoute']); 2 //路由的配置: 3 app.config(function($routeProvider) { 4 //我们在实现I want you项目,自己实现了一个路由, 5 //在这里angular.js帮我们实现了一个路由 6 7 var routeconfig = { 8 templateUrl: "body.html", 9 controller: "myTodoCtrl" 10 /*controller: 'myTodoCtrl'*/ 11 } 12 13 var ohter_config = { 14 templateUrl: "other.html" 15 } 16 //如果路由没有匹配到hash,让它跳到body.html 17 //如果路由器配到的hash是index.html#/all 或者 18 //index.html#/comp index.html#/status 19 //假设路由器的匹配路径是 index.html#/!/allssssssssss 20 //会匹配失败,会通过otherwise,让它自动重定向到 index.html#/all 21 $routeProvider. 22 when("",routeconfig). 23 //status : 它对应我们页面的hash: all completed active 24 //路由规则的优先级按写法的顺序所决定的 25 when("/other", ohter_config). 26 when("/:status_id", routeconfig ). 27 otherwise( { redirectTo: "/all" }); 28 });
上面一段就是路由部分。事实上,这个网页主要的部分就是路由和各种方法,路由解决了,剩下的就好办多了。
首先,我们编写过滤器。因为剩下的各种功能的方法组件等都是独立的,所以基本上书写顺序无所谓。但是为了安全起见(忘了写,漏了写就尴尬了),这里按照网页从上往下的执行顺序,碰到什么写什么。
过滤器的代码是这个——
1 app.filter("createtimeSort", function(){ 2 return function(list){ 3 if(list) { 4 return list.sort(function(a, b){ 5 return b.time - a.time; 6 }); 7 }else { 8 return []; 9 } 10 11 } 12 }); 13 app.filter("offset", function(){ 14 return function(list){ 15 var res = []; 16 17 } 18 })
过滤器使用的地方是这个——
<li ng-repeat="item in itemList|filter:filterStatus|createtimeSort track by $index" ....>
首先,第一个是遍历item in itemList,然后是第一个过滤器|filter:filterStatus,这个过滤器是写在后面的,通过判断filterStatus的对象来判断这个标签和内容是否应该隐藏——
1 $scope.$on('$routeChangeSuccess', function () { 2 //使用这个实时监听功能,是有条件, 3 //必须要配置路由器对象,才可以监听路由器的变化。 4 console.log('hash值改变了'); 5 console.log($routeParams.status_id); 6 if($routeParams.status_id === "all") { 7 $scope.filterStatus = {}; 8 $scope.routName = "all"; 9 }else if($routeParams.status_id === "active") { 10 $scope.filterStatus = {completed:false}; 11 $scope.routName = "active"; 12 }else { 13 $scope.routName = "completed"; 14 $scope.filterStatus = {completed:true}; 15 } 16 //该功能可以实时监听该模块作用域下hash值的改变 17 });
当路由为all的时候,没有反应,直接跳过。
当路由为active的时候,留下{completed:false},即complete属性为false的条目(这个属性后面介绍,所以才写在最下面的)
其余情况和上面一条相反,即留下{completed:true}的条目。
createtimeSort过滤器要求我们重新排列标签,【以保证刚输入的数据出现在最上面,然后依次向下】。
angular中要求条目不能有重复,如["aaa",’aaa","aaa"],如果有标签repeate这个,就会报错。因为angular不能对他们进行唯一性的判断(即,不好追踪),于是最后的track by就是判断用的,判断的依据是$index,即索引变量,这个是唯一的。
接下来的:
1 function store(namespace, data) { 2 if(arguments.length > 1) { 3 localStorage.setItem(namespace, JSON.stringify(data)); 4 }else { 5 var obj = localStorage.getItem(namespace); 6 return (obj && JSON.parse(obj)) || null 7 } 8 }
存储方法,中间有两个参数,第一个是参数的名字,第二个是值。参数会通过location方法存储起来。
1 app.directive('todoFocus', function(){ 2 var linkFunction_nice = function(scope, element, attr) { 3 //console.log(attr, element); 4 scope.$watch(attr.todoFocus, function(newval){ 5 setTimeout(function(){ 6 element[0].focus(); 7 //延迟执行,否则无法聚焦 8 }, 100); 9 }); 10 }; 11 12 return { 13 restrict: "A", //暴露的一个元素,若是‘A’则是属性 14 link: linkFunction_nice 15 }; 16 })
这个是自定义指令todoFocus,作用是当我们双击了条目的时候,会出现光标闪烁,表示可以编辑。这个使用在这里——
<input todo-focus="item.edit_status" class="edit" ng-blur="saveEdit(item)" ng-model="item.title">
当"item.edit_status" 处于可编辑状态的时候,它会显示,读取条目内容。当失去焦点的时候,对内容进行保存 ng-blur="saveEdit(item)"。
接下来,就是控制器的书写了——
1 app.controller("myTodoCtrl", function($scope, $routeParams, $filter){ 2 3 $scope.itemList = store('mytodo') || itemList;//进行核心数据的绑定 4 $scope.routName = "all"; 5 $scope.newTodo = ''; 6 $scope.$watch("itemList", function(){ 7 //$scope.remainCount = getRemainCount(itemList);// 计算未完成的任务数量 8 $scope.remainCount = $filter('filter')($scope.itemList, { 9 completed: false 10 }).length; // 计算未完成的任务数量 11 12 store('mytodo', $scope.itemList); 13 }, true); 14 $scope.saveEdit = function(obj){ 15 console.log('失去焦点'); 16 17 obj.edit_status = false; 18 } 19 $scope.remove = function(obj){ 20 var index = $scope.itemList.indexOf(obj); 21 console.log('得到要删除对象的相应索引值:', index); 22 $scope.itemList.splice(index, 1); 23 24 } 25 $scope.editTodo = function(todo){ 26 console.log('进行双击操作'); 27 todo.edit_status = true; 28 } 29 $scope.markAll = function(status){ 30 //全部选中的功能 31 $scope.itemList.forEach(function(obj, index){ 32 if(obj.completed !== status) { 33 obj.completed = status; 34 } 35 //全选的交替操作 36 }); 37 } 38 $scope.clearCompleted = function(){ 39 //清楚所有的完成状态任务 40 $scope.itemList = $filter('filter')($scope.itemList, { 41 completed: false 42 }); 43 } 44 $scope.addTodo = function(){ 45 //console.log($scope.newTodo); 46 //console.log($scope.newTodotext); 47 //增加未完成的任务操作 48 if(!$scope.newTodo.trim()) { 49 return; 50 } 51 var Coreobj = { 52 //已完成 53 completed: false, 54 title: $scope.newTodo, 55 time: new Date().getTime() 56 } 57 $scope.itemList.push(Coreobj); 58 $scope.newTodo = ''; 59 } 60 61 62 63 $scope.$on('$routeChangeSuccess', function () { 64 //使用这个实时监听功能,是有条件, 65 //必须要配置路由器对象,才可以监听路由器的变化。 66 console.log('hash值改变了'); 67 console.log($routeParams.status_id); 68 if($routeParams.status_id === "all") { 69 $scope.filterStatus = {}; 70 $scope.routName = "all"; 71 }else if($routeParams.status_id === "active") { 72 $scope.filterStatus = {completed:false}; 73 $scope.routName = "active"; 74 }else { 75 $scope.routName = "completed"; 76 $scope.filterStatus = {completed:true}; 77 } 78 //该功能可以实时监听该模块作用域下hash值的改变 79 }); 80 });
控制器分为两部分,数据部分和方法部分。
13行之前属于数据部分,主要进行各种定义和计算。如剩余任务个数计算
$scope.$watch("itemList", function(){
7 //$scope.remainCount = getRemainCount(itemList);// 计算未完成的任务数量
8 $scope.remainCount = $filter('filter')($scope.itemList, {
9 completed: false
10 }).length;
这个剩余任务的计算,是通过监听条目的变化进行触发的,过滤器方法输入后,将completed等于false的剔除,得到的一组新的数组,然后这个新的数组的长度便是未完成的任务数了。
剩下的方法就不作介绍了,非常简单。