Commit 6f8b0d9b authored by dmitriz's avatar dmitriz

angularjs-perf: Simplified functions

parent 8d40a1c0
...@@ -12,21 +12,21 @@ ...@@ -12,21 +12,21 @@
<header id="header"> <header id="header">
<h1>todos</h1> <h1>todos</h1>
<form id="todo-form" ng-submit="TC.addTodo()"> <form id="todo-form" ng-submit="TC.addTodo()">
<input id="new-todo" placeholder="What needs to be done?" ng-model="TC.newTodo" autofocus> <input id="new-todo" placeholder="What needs to be done?" ng-model="TC.newTodo.title" autofocus>
</form> </form>
</header> </header>
<section id="main" ng-show="TC.todos.length" ng-cloak> <section id="main" ng-show="TC.todos.length" ng-cloak>
<input id="toggle-all" type="checkbox" ng-model="TC.allChecked" ng-click="TC.markAll(TC.allChecked)"> <input id="toggle-all" type="checkbox" ng-model="TC.allChecked" ng-click="TC.markAll(TC.allChecked)">
<label for="toggle-all">Mark all as complete</label> <label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"> <ul id="todo-list">
<li ng-repeat="todo in TC.todos | filter:TC.statusFilter track by $index" ng-class="{completed: todo.completed, editing: todo == TC.editedTodo}"> <li ng-repeat="todo in TC.todos | filter:TC.statusFilter track by $index" ng-class="{completed: todo.completed, editing: todo === TC.editedTodo}">
<div class="view"> <div class="view">
<input class="toggle" type="checkbox" ng-model="todo.completed" ng-change="TC.todoCompleted(todo)"> <input class="toggle" type="checkbox" ng-model="todo.completed">
<label ng-dblclick="TC.editTodo(todo)">{{todo.title}}</label> <label ng-dblclick="TC.editTodo(todo)">{{todo.title}}</label>
<button class="destroy" ng-click="TC.removeTodo(todo)"></button> <button class="destroy" ng-click="TC.removeTodo($index)"></button>
</div> </div>
<form ng-submit="TC.doneEditing(todo)"> <form ng-submit="TC.doneEditing(todo, $index)">
<input class="edit" ng-trim="false" ng-model="todo.title" ng-blur="TC.doneEditing(todo)" todo-escape="TC.revertEditing(todo)" todo-focus="todo == TC.editedTodo"> <input class="edit" ng-trim="false" ng-model="todo.title" ng-blur="TC.doneEditing(todo, $index)" todo-escape="TC.revertEditing($index)" todo-focus="todo === TC.editedTodo">
</form> </form>
</li> </li>
</ul> </ul>
......
...@@ -9,13 +9,13 @@ ...@@ -9,13 +9,13 @@
* - retrieves and persists the model via the todoStorage service * - retrieves and persists the model via the todoStorage service
* - exposes the model to the template and provides event handlers * - exposes the model to the template and provides event handlers
*/ */
.controller('TodoCtrl', function TodoCtrl($scope, $location, $filter, todoStorage) { .controller('TodoCtrl', function TodoCtrl($scope, $location, todoStorage) {
var TC = this; var TC = this;
var todos = TC.todos = todoStorage.get(); var todos = TC.todos = todoStorage.get();
TC.newTodo = ''; TC.newTodo = {title: '', completed: false};
TC.remainingCount = $filter('filter')(todos, {completed: false}).length;
TC.editedTodo = null; TC.editedTodo = {};
if ($location.path() === '') { if ($location.path() === '') {
$location.path('/'); $location.path('/');
...@@ -27,73 +27,61 @@ ...@@ -27,73 +27,61 @@
TC.statusFilter = { '/active': {completed: false}, '/completed': {completed: true} }[path]; TC.statusFilter = { '/active': {completed: false}, '/completed': {completed: true} }[path];
}); });
$scope.$watch('TC.remainingCount == 0', function (val) { // 3rd argument `true` for deep object watching
TC.allChecked = val; $scope.$watch('TC.todos', function () {
}); TC.remainingCount = todos.filter(function (todo) { return !todo.completed; }).length;
TC.allChecked = (TC.remainingCount === 0);
// Save any changes to localStorage
todoStorage.put(todos);
}, true);
TC.addTodo = function () { TC.addTodo = function () {
var newTodo = TC.newTodo.trim(); var newTitle = TC.newTodo.title = TC.newTodo.title.trim();
if (newTodo.length === 0) { if (newTitle.length === 0) {
return; return;
} }
todos.push({ todos.push(TC.newTodo);
title: newTodo,
completed: false
});
todoStorage.put(todos);
TC.newTodo = ''; TC.newTodo = {title: '', completed: false};
TC.remainingCount++;
}; };
TC.editTodo = function (todo) { TC.editTodo = function (todo) {
TC.editedTodo = todo; TC.editedTodo = todo;
// Clone the original todo to restore it on demand. // Clone the original todo to restore it on demand.
TC.originalTodo = angular.extend({}, todo); TC.originalTodo = angular.copy(todo);
}; };
TC.doneEditing = function (todo) { TC.doneEditing = function (todo, index) {
TC.editedTodo = null; TC.editedTodo = {};
todo.title = todo.title.trim(); todo.title = todo.title.trim();
if (!todo.title) { if (!todo.title) {
TC.removeTodo(todo); TC.removeTodo(index);
} }
todoStorage.put(todos);
}; };
TC.revertEditing = function (todo) { TC.revertEditing = function (index) {
todos[todos.indexOf(todo)] = TC.originalTodo; todos[index] = TC.originalTodo;
TC.doneEditing(TC.originalTodo); TC.doneEditing(TC.originalTodo);
}; };
TC.removeTodo = function (todo) { TC.removeTodo = function (index) {
TC.remainingCount -= todo.completed ? 0 : 1; todos.splice(index, 1);
todos.splice(todos.indexOf(todo), 1);
todoStorage.put(todos);
};
TC.todoCompleted = function (todo) {
TC.remainingCount += todo.completed ? -1 : 1;
todoStorage.put(todos);
}; };
TC.clearCompletedTodos = function () { TC.clearCompletedTodos = function () {
TC.todos = todos = todos.filter(function (val) { TC.todos = todos = todos.filter(function (val) {
return !val.completed; return !val.completed;
}); });
todoStorage.put(todos);
}; };
TC.markAll = function (completed) { TC.markAll = function (completed) {
todos.forEach(function (todo) { todos.forEach(function (todo) {
todo.completed = completed; todo.completed = completed;
}); });
TC.remainingCount = completed ? 0 : todos.length;
todoStorage.put(todos);
}; };
}); });
})(); })();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment