Angular.js Simple Todo, Store, Redux
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('todoApp', []); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html ng-app="todoApp"> | |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/EventEmitter/4.3.0/EventEmitter.min.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.0.4/redux.min.js"></script> | |
<script src="application.js"></script> | |
<script src="store.js"></script> | |
<script src="service.js"></script> | |
<script src="todo-actions.js"></script> | |
<script src="todos.js"></script> | |
<script src="todo-remaining.js"></script> | |
<script src="todo-create.js"></script> | |
</head> | |
<body> | |
<h2>Todo</h2> | |
<todo-remaining></todo-remaining> | |
<todos></todos> | |
<todo-create></todo-create> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function todoRepository(todoStore, $q) { | |
this.$q = $q; | |
this.store = todoStore; | |
this.todos = [ | |
{id: 1, text:'learn angular', done:true}, | |
{id: 2, text:'build an angular app', done:false} | |
]; | |
this.nextId = 3; | |
} | |
todoRepository.prototype.findAll = function() { | |
return this.$q.when(angular.copy(this.todos)); | |
} | |
todoRepository.prototype.update = function(todo) { | |
var index = this.todos.findIndex(function(elt) { return elt.id === todo.id }); | |
if (index !== -1) { | |
this.todos[index] = todo; | |
} | |
return this.$q.when(angular.copy(todo)); | |
} | |
todoRepository.prototype.create = function(todo) { | |
var newTodo = angular.copy(todo); | |
newTodo.id = this.nextId; | |
this.nextId++; | |
this.todos.push(newTodo); | |
return this.$q.when(newTodo); | |
} | |
todoRepository.prototype.archive = function() { | |
this.todos = this.todos.filter(function(todo) { | |
return !todo.done; | |
}); | |
return this.$q.when(angular.copy(this.todos)); | |
} | |
angular.module('todoApp').service('todoRepository', todoRepository); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function todoReducer(state, action) { | |
switch (action.type) { | |
case 'add-todo': | |
var newState = state.slice(); | |
newState.push(angular.copy(action.todo)); | |
return newState; | |
case 'update-todo': | |
return state.map(function(todo) { | |
if (todo.id === action.todo.id) { | |
return angular.copy(action.todo); | |
} else { | |
return todo; | |
} | |
}); | |
case 'load-todos': | |
return action.todos.slice(); | |
default: | |
return state; | |
} | |
} | |
function promiseMiddleware(store) { | |
return function(next) { | |
return function(action) { | |
return action && typeof action.then === 'function' | |
? action.then(result => store.dispatch(result)) | |
: next(action); | |
} | |
} | |
} | |
angular.module('todoApp').factory('todoStore', function() { | |
var createStoreWithMiddleware = Redux.applyMiddleware(promiseMiddleware)(Redux.createStore); | |
return createStoreWithMiddleware(todoReducer, []); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function TodoActions(todoRepository) { | |
this.repository = todoRepository; | |
} | |
TodoActions.prototype.addTodo = function(todo) { | |
return this.repository.create(todo).then(function(createdTodo) { | |
return { | |
type: 'add-todo', | |
todo: createdTodo | |
}; | |
}); | |
} | |
TodoActions.prototype.updateTodo = function(todo) { | |
return this.repository.update(todo).then(function(updatedTodo) { | |
return { | |
type: 'update-todo', | |
todo: updatedTodo | |
}; | |
}); | |
} | |
TodoActions.prototype.loadTodos = function() { | |
return this.repository.findAll().then(function(todos) { | |
return { | |
type: 'load-todos', | |
todos: todos | |
}; | |
}); | |
} | |
TodoActions.prototype.archiveTodos = function() { | |
return this.repository.archive().then(function(todos) { | |
return { | |
type: 'load-todos', | |
todos: todos | |
}; | |
}); | |
} | |
angular.module('todoApp').service('todoActions', TodoActions); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('todoApp').directive('todoCreate', function() { | |
return { | |
restrict: 'E', | |
scope: true, | |
controller: function($scope, todoStore, todoActions) { | |
$scope.newTodo = {}; | |
$scope.addTodo = function() { | |
todoStore.dispatch(todoActions.addTodo($scope.newTodo)).then(function() { | |
$scope.newTodo = {}; | |
}); | |
}; | |
}, | |
template: ` | |
<form ng-submit="addTodo()"> | |
<input type="text" ng-model="newTodo.text" size="30" | |
placeholder="add new todo here"> | |
<input class="btn-primary" type="submit" value="add"> | |
</form> | |
` | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('todoApp').directive('todoRemaining', function() { | |
return { | |
restrict: 'E', | |
scope: true, | |
controller: function($scope, todoStore, todoActions) { | |
todoStore.dispatch(todoActions.loadTodos()); | |
$scope.todos = todoStore.getState(); | |
todoStore.subscribe(function(todos) { | |
$scope.todos = todoStore.getState(); | |
}); | |
$scope.remaining = function() { | |
var count = 0; | |
angular.forEach($scope.todos, function(todo) { | |
count += todo.done ? 0 : 1; | |
}); | |
return count; | |
}; | |
$scope.archive = function() { | |
todoStore.dispatch(todoActions.archiveTodos()); | |
}; | |
}, | |
template: ` | |
<span>{{remaining()}} of {{todos.length}} remaining</span> | |
[ <a href="" ng-click="archive()">archive</a> ] | |
` | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('todoApp').directive('todos', function() { | |
return { | |
restrict: 'E', | |
scope: true, | |
controller: function($scope, todoStore, todoActions) { | |
todoStore.dispatch(todoActions.loadTodos()); | |
$scope.todos = todoStore.getState(); | |
todoStore.subscribe(function(todos) { | |
$scope.todos = todoStore.getState(); | |
}); | |
$scope.update = function(todo) { | |
todoActions.updateTodo(todo); | |
} | |
}, | |
template: ` | |
<ul class="unstyled"> | |
<li ng-repeat="todo in todos"> | |
<input type="checkbox" ng-model="todo.done" ng-change="update(todo)"> | |
<span class="done-{{todo.done}}">{{todo.text}}</span> | |
</li> | |
</ul> | |
` | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment