Commit ff0a29ce authored by Pascal Hartig's avatar Pascal Hartig

Improvements, switch to angular base version

- Strict mode
- Split up directives
- Require 'app' in 'main' to improve loading time
- Added Igor to contributors list
parent 9b3f7f1e
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<ul id="todo-list"> <ul id="todo-list">
<li ng-repeat="todo in todos | filter:statusFilter" ng-dblclick="editTodo(todo)" ng-class="{completed: todo.completed, editing: todo == editedTodo}"> <li ng-repeat="todo in todos | filter:statusFilter" ng-dblclick="editTodo(todo)" ng-class="{completed: todo.completed, editing: todo == editedTodo}">
<div class="view"> <div class="view">
<input class="toggle" type="checkbox" ng-model="todo.completed" ng-change="todoCompleted(todo)"> <input class="toggle" type="checkbox" ng-model="todo.completed">
<label>{{todo.title}}</label> <label>{{todo.title}}</label>
<button class="destroy" ng-click="removeTodo(todo)"></button> <button class="destroy" ng-click="removeTodo(todo)"></button>
</div> </div>
...@@ -64,7 +64,13 @@ ...@@ -64,7 +64,13 @@
</section> </section>
<footer id="info"> <footer id="info">
<p>Double-click to edit a todo.</p> <p>Double-click to edit a todo.</p>
<p>Credits: <a href="http://twitter.com/cburgdorf">Christoph Burgdorf</a>, <a href="http://ericbidelman.com">Eric Bidelman</a>, <a href="http://jacobmumm.com">Jacob Mumm</a>, <a href="https://twitter.com/passy">Pascal Hartig</a></p> <p>Credits:
<a href="http://twitter.com/cburgdorf">Christoph Burgdorf</a>,
<a href="http://ericbidelman.com">Eric Bidelman</a>,
<a href="http://jacobmumm.com">Jacob Mumm</a>,
<a href="http://igorminar.com">Igor Minar</a> and
<a href="http://twitter.com/passy">Pascal Hartig</a>
</p>
</footer> </footer>
<script src="../../../assets/base.js"></script> <script src="../../../assets/base.js"></script>
<script data-main="js/main" src="../../../assets/require.min.js"></script> <script data-main="js/main" src="../../../assets/require.min.js"></script>
......
'use strict';
define([], function () { define([], function () {
return angular.module('todomvc', []); return angular.module('todomvc', []);
}); });
'use strict';
/** /**
* The main controller for the app. The controller: * The main controller for the app. The controller:
* - retrieves and persist the model via the todoStorage service * - retrieves and persist the model via the todoStorage service
* - * - exposes the model to the template and provides event handlers
* exposes the model to the template and
*/ */
define(['app', 'services/todoStorage'], function (app) { define(['app', 'services/todoStorage'], function (app) {
...@@ -11,34 +11,36 @@ define(['app', 'services/todoStorage'], function (app) { ...@@ -11,34 +11,36 @@ define(['app', 'services/todoStorage'], function (app) {
var todos = $scope.todos = todoStorage.get(); var todos = $scope.todos = todoStorage.get();
$scope.newTodo = ""; $scope.newTodo = "";
$scope.remainingCount = filterFilter(todos, {completed: false}).length;
$scope.editedTodo = null; $scope.editedTodo = null;
$scope.$watch('todos', function() {
$scope.remainingCount = filterFilter(todos, {completed: false}).length;
$scope.doneCount = todos.length - $scope.remainingCount;
$scope.allChecked = !$scope.remainingCount
todoStorage.put(todos);
}, true);
if ( $location.path() === '' ) $location.path('/'); if ( $location.path() === '' ) $location.path('/');
$scope.location = $location; $scope.location = $location;
$scope.$watch('location.path()', function( path ) { $scope.$watch( 'location.path()', function( path ) {
$scope.statusFilter = (path == '/active') ? $scope.statusFilter = (path == '/active') ?
{ completed: false } : (path == '/completed') ? { completed: false } : (path == '/completed') ?
{ completed: true } : null; { completed: true } : null;
}); });
$scope.$watch('remainingCount == 0', function( val ) {
$scope.allChecked = val;
});
$scope.addTodo = function() { $scope.addTodo = function() {
if ($scope.newTodo.length === 0) return; if ( !$scope.newTodo.length ) {
return;
}
todos.push({ todos.push({
title: $scope.newTodo, title: this.newTodo,
completed: false completed: false
}); });
todoStorage.put(todos);
$scope.newTodo = ''; this.newTodo = '';
$scope.remainingCount++;
}; };
...@@ -49,21 +51,14 @@ define(['app', 'services/todoStorage'], function (app) { ...@@ -49,21 +51,14 @@ define(['app', 'services/todoStorage'], function (app) {
$scope.doneEditing = function( todo ) { $scope.doneEditing = function( todo ) {
$scope.editedTodo = null; $scope.editedTodo = null;
if ( !todo.title ) $scope.removeTodo(todo); if ( !todo.title ) {
todoStorage.put(todos); $scope.removeTodo(todo);
}
}; };
$scope.removeTodo = function( todo ) { $scope.removeTodo = function( todo ) {
$scope.remainingCount -= todo.completed ? 0 : 1;
todos.splice(todos.indexOf(todo), 1); todos.splice(todos.indexOf(todo), 1);
todoStorage.put(todos);
};
$scope.todoCompleted = function( todo ) {
todo.completed ? $scope.remainingCount-- : $scope.remainingCount++;
todoStorage.put(todos);
}; };
...@@ -71,7 +66,6 @@ define(['app', 'services/todoStorage'], function (app) { ...@@ -71,7 +66,6 @@ define(['app', 'services/todoStorage'], function (app) {
$scope.todos = todos = todos.filter(function( val ) { $scope.todos = todos = todos.filter(function( val ) {
return !val.completed; return !val.completed;
}); });
todoStorage.put(todos);
}; };
...@@ -79,8 +73,6 @@ define(['app', 'services/todoStorage'], function (app) { ...@@ -79,8 +73,6 @@ define(['app', 'services/todoStorage'], function (app) {
todos.forEach(function( todo ) { todos.forEach(function( todo ) {
todo.completed = done; todo.completed = done;
}); });
$scope.remainingCount = done ? 0 : todos.length;
todoStorage.put(todos);
}; };
} }
]); ]);
......
/**
* Directive that executes an expression when the element it is applied to loses focus.
*/
define(['app'], function (app) {
app.directive('todoBlur', function() {
return function( scope, elem, attrs ) {
elem.bind('blur', function() {
scope.$apply( attrs.todoBlur );
});
};
});
app.directive('todoFocus', function( $timeout ) {
return function( scope, elem, attrs ) {
scope.$watch( attrs.todoFocus, function( newval ) {
if ( newval ) {
$timeout(function() {
elem[0].focus();
elem[0].select();
}, 0 );
}
});
};
});
});
'use strict';
/**
* Directive that executes an expression when the element it is applied to loses focus.
*/
define(['app'], function ( app ) {
app.directive('todoBlur', function() {
return function( scope, elem, attrs ) {
elem.bind('blur', function() {
scope.$apply(attrs.todoBlur);
});
};
});
});
'use strict';
/**
* Directive that places focus on the element it is applied to when the expression it binds to evaluates to true.
*/
define(['app'], function ( app ) {
app.directive('todoFocus', function( $timeout ) {
return function( scope, elem, attrs ) {
scope.$watch(attrs.todoFocus, function( newval ) {
if ( newval ) {
$timeout(function() {
elem[0].focus();
elem[0].select();
}, 0, false);
}
});
};
});
});
// Author: Pascal Hartig <phartig@weluse.de> 'use strict';
// Filename: main.js
require.config({ require.config({
paths: { paths: {
...@@ -12,8 +11,6 @@ require.config({ ...@@ -12,8 +11,6 @@ require.config({
} }
}); });
require(['angular', 'controllers/todo', 'directives/todo'], function (angular) { require(['angular', 'app', 'controllers/todo', 'directives/todoFocus', 'directives/todoBlur'], function (angular) {
angular.bootstrap(document, ['todomvc']); angular.bootstrap(document, ['todomvc']);
}); });
// vim:sts=4:sw=4:ft=javascript
'use strict';
/** /**
* Services that persists and retrieves TODOs from localStorage. * Services that persists and retrieves TODOs from localStorage.
*/ */
......
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