todomvc-app

1、HTML

 1 <!doctype html>
 2 <html lang="en">
 3     <head>
 4         <meta charset="utf-8">
 5         <meta name="viewport" content="width=device-width, initial-scale=1">
 6         <title>Template • TodoMVC</title>
 7         <link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
 8         <!-- CSS overrides - remove if you don't need it -->
 9         <link rel="stylesheet" href="css/app.css">
10     </head>
11     <body ng-app="MyTodoMvc">
12         <section class="todoapp" ng-controller="MainController">
13             <header class="header">
14                 <h1>todos</h1>
15                 <form ng-submit="add()">
16                     <input class="new-todo" placeholder="What needs to be done?" ng-model="text" autofocus>
17                 </form>
18             </header>
19             <section class="main">
20                 <input class="toggle-all" type="checkbox" ng-click="toggleAll()">
21                 <label for="toggle-all">Mark all as complete</label>
22                 <ul class="todo-list">
23                     <li ng-repeat="todo in todos | filter: selector : equalCompare" ng-class="{completed:todo.completed,editing:todo.id===currentEditingId}" data-id="{{todo.id}}">
24                         <div class="view">
25                             <input class="toggle" type="checkbox" ng-model="todo.completed">
26                             <label ng-dblclick="editing(todo.id)">{{todo.text}}</label>
27                             <button class="destroy" ng-click="remove(todo.id)"></button>
28                         </div>
29                         <form ng-submit="save()">
30                             <input class="edit" ng-model="todo.text" ng-blur="save()">
31                         </form>
32                     </li>
33                 </ul>
34             </section>
35             <!-- This footer should hidden by default and shown when there are todos -->
36             <footer class="footer">
37                 <!-- This should be `0 items left` by default -->
38                 <span class="todo-count"><strong>{{todos.length}}</strong> item left</span>
39                 <!-- Remove this if you don't implement routing -->
40                 <ul class="filters">
41                     <li>
42                         <a ng-class="{selected:$location.path() == '/'}" href="#/">All</a>
43                     </li>
44                     <li>
45                         <a ng-class="{selected:$location.path() == '/active'}" href="#/active">Active</a>
46                     </li>
47                     <li>
48                         <a ng-class="{selected:$location.path() == '/completed'}" href="#/completed">Completed</a>
49                     </li>
50                 </ul>
51                 <!-- Hidden if no completed items are left ↓ -->
52                 <button class="clear-completed" ng-click="clear()" ng-show="existCompleted()">Clear completed</button>
53             </footer>
54         </section>
55         <footer class="info">
56             <p>Double-click to edit a todo</p>
57             <!-- Remove the below line ↓ -->
58             <p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
59             <!-- Change this out with your name and url ↓ -->
60             <p>Created by <a href="http://todomvc.com">you</a></p>
61             <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
62         </footer>
63         <!-- Scripts here. Don't remove ↓ -->
64         <script src="node_modules/angular/angular.js"></script>
65         <script src="js/app.js"></script>
66     </body>
67 </html>

2、app.js

  1 (function(angular) {
  2   'use strict';
  3 
  4 
  5   // 1. 为应用程序创建一个模块,用来管理界面的结构
  6   var myApp = angular.module('MyTodoMvc', []);
  7 
  8   // 2. 注册一个主要的控制器(属于某个模块),用于往视图(view)中暴露数据
  9   myApp.controller('MainController', ['$scope', '$location', function($scope, $location) {
 10     // [1,2,3,4,5]
 11     // 获取唯一ID
 12     function getId() {
 13       var id = Math.random(); // 1 2
 14       for (var i = 0; i < $scope.todos.length; i++) {
 15         if ($scope.todos[i].id === id) {
 16           id = getId();
 17           break;
 18         }
 19       }
 20       return id;
 21     }
 22 
 23     // 文本框需要一个模型,为了拿到文本输入的值
 24     $scope.text = '';
 25 
 26     // 任务列表也需要一个
 27     // 每一个任务的结构 { id: 1, text: '学习', completed: true }
 28     $scope.todos = [{
 29       id: 0.123,
 30       text: '学习',
 31       completed: false
 32     }, {
 33       id: 0.22,
 34       text: '睡觉',
 35       completed: false
 36     }, {
 37       id: 0.232,
 38       text: '打豆豆',
 39       completed: true
 40     }];
 41 
 42     // 添加todo
 43     $scope.add = function() {
 44       if (!$scope.text) {
 45         return;
 46       }
 47       $scope.todos.push({
 48         // 自动增长?
 49         id: getId(),
 50         // 由于$scope.text是双向绑定的,add同时肯定可以同他拿到界面上的输入
 51         text: $scope.text,
 52         completed: false
 53       });
 54       // 清空文本框
 55       $scope.text = '';
 56     };
 57 
 58 
 59     // 处理删除
 60     $scope.remove = function(id) {
 61       // 删除谁
 62       for (var i = 0; i < $scope.todos.length; i++) {
 63         if ($scope.todos[i].id === id) {
 64           $scope.todos.splice(i, 1);
 65           break;
 66         }
 67       }
 68       // $scope.todos
 69     };
 70 
 71     // 清空已完成
 72     $scope.clear = function() {
 73       var result = [];
 74       for (var i = 0; i < $scope.todos.length; i++) {
 75         if (!$scope.todos[i].completed) {
 76           result.push($scope.todos[i]);
 77         }
 78       }
 79       $scope.todos = result;
 80     };
 81 
 82     // 是否有已经完成的
 83     $scope.existCompleted = function() {
 84       // 该函数一定要有返回值
 85       for (var i = 0; i < $scope.todos.length; i++) {
 86         if ($scope.todos[i].completed) {
 87           return true;
 88         }
 89       }
 90       return false;
 91     };
 92 
 93     // 当前编辑哪个元素
 94     $scope.currentEditingId = -1;
 95     // -1代表一个肯定不存在的元素,默认没有任何被编辑
 96     $scope.editing = function(id) {
 97       $scope.currentEditingId = id;
 98     };
 99     $scope.save = function() {
100       $scope.currentEditingId = -1;
101     };
102 
103     // $scope.checkall = false;
104     // $scope.$watch('checkall', function(now, old) {
105     //   for (var i = 0; i < $scope.todos.length; i++) {
106     //     $scope.todos[i].completed = now;
107     //   }
108     // });
109 
110     var now = true;
111     $scope.toggleAll = function() {
112       for (var i = 0; i < $scope.todos.length; i++) {
113         $scope.todos[i].completed = now;
114       }
115       now = !now;
116     }
117 
118     // 状态筛选
119     $scope.selector = {}; // {} {completed:true} {completed:false}
120     // 点击事件的方式不合适,有DOM操作
121     // 让$scope也有一个指向$location的数据成员
122     $scope.$location = $location;
123     // watch只能监视属于$scope的成员
124     $scope.$watch('$location.path()', function(now, old) {
125       // 1. 拿到锚点值
126       // 这样写就要求执行环境必须要有window对象
127       // var hash = window.location.hash;
128       // console.log($location);
129       // console.log(now);
130       // 2. 根据锚地值对selector做变换
131       switch (now) {
132         case '/active':
133           $scope.selector = { completed: false };
134           break;
135         case '/completed':
136           $scope.selector = { completed: true };
137           break;
138         default:
139           $scope.selector = {};
140           break;
141       }
142     });
143 
144     // 自定义比较函数, 默认filter过滤器使用的是模糊匹配
145     $scope.equalCompare = function(source, target) {
146       // console.log(source);
147       // console.log(target);
148       // return false;
149       return source === target;
150     };
151 
152 
153   }]);
154 
155 })(angular);

 

posted @ 2018-04-15 22:26  半指温柔乐  阅读(401)  评论(0编辑  收藏  举报