TODO в AngularJS
После примеров про Hello world, Echo и простой калькулятор, создание списка TODO - это один из ритуальных пассажей для вхождения в мир программирования на любом языке в любом окружении. Давайте посмотрим, как реализовать TODO на AngularJS.
Простой список TODO
После загрузки angular.min.js мы создаем модуль AngularJS с именем todoApp и контролллер todoController. Внутри контроллера мы создаем пустой массив tasks, где будет содержаться список todo. Мы сделаем его атрибутом текущего $scope, чтобы иметь возможность доступа из HTML.
Мы также объявляем функцию add (тоже атрибут $scope), которая получает значение title (Как мы позже увидим, это будет имя поля для ввода), и добавляем его в список задач, используя push. Вот и весь JavaScript, который нам нужен для простого списка TODO.
В части HTML у нас есть элемент div, который определяет область AngularJS-приложения ng-app и AngularJS-контроллера ng-controller.
Внутри контролллера в HTML у нас есть две части. Первая часть это поле для ввода input, связанное с атрибутом $scope.title с помощью ng-model, и кнопка, использующая ng-click для вызова метода $scope.add при нажатии.
Вторая часть использует директиву ng-repeat для прохода по элементам массива $scope.tasks и показа их в виде списка.
examples/angular/todo1.html
<script src="angular.min.js"></script> <script> angular.module('todoApp', []) .controller('todoController', function($scope){ $scope.tasks = []; $scope.add = function() { $scope.tasks.push($scope.title); } }) </script> <div ng-app="todoApp" ng-controller="todoController"> <input ng-model="title"><button ng-click="add()">Add</button> <ul> <li ng-repeat="t in tasks">{{ t }}</li> </ul> </div>Try!
Активация поля ввода нажатием ENTER
Несколько обременительно нажимать кнопку для добавления каждого элемента. Будет гораздо лучше, если мы сможем просто нажимать ENTER. Чтобы это сделать, нам нужно обернуть элемент input в form и на форму добавить директиву ng-submit, которая будет вызывать функцию $scope.add. А также для избежания повторного вызова функции $scope.add.
<form ng-submit="add()"> <input ng-model="title"><button>Add</button> </form>
Дублирующиеся значения в ng-repeat
Если вы попробовали пример выше, то могли заметить, что добавление того же элемента дважды приводит к падению приложения. Причина в том, что директива ng-repeat расчитана на уникальные значения в массиве. Я не уверен, что наличие одинаковых значений в списке TODO это хорошо, но сейчас я бы хотел позволить пользователю добавлять то же самое значение дважды. Для этого мы можем указать ng-repeat использовать $index массива для перебора значений:
<li ng-repeat="t in tasks track by $index">{{ t }}</li>
Удаление элемента из списка TODO
Хотя для большинства из нас реальность такова, что TODO список всегда увеличивается, иногда удача нам сопутствует и дела выполняются. (Или они просто отменяются.) Мы бы хотели иметь способ удалить элемент. Для этого мы собираемся добавить кнопку в конце каждого пункта, которая будет удалять конкретный элемент из списка дел.
Добавить кнопку это просто:
<button ng-click="delete()">x</button>
Соответствующая кнопке функция delete заставила меня почесать голову, но в итоге я справился:
$scope.delete = function() { $scope.tasks.splice(this.$index, 1); }
Когда вызывается функция delete, this содержит атрибут $index, который похоже указывает на индекс текущего элемента.
Мы можем использовать это для нахождения нужного элемента в массива tasks. Функция JavaScript splice удалит один элемент из массива,
а список сразу же обновится на HTML-странице.
examples/angular/todo2.html
<script src="angular.min.js"></script>
<script>
angular.module('todoApp', [])
.controller('todoController', function($scope) {
$scope.tasks = [];
$scope.add = function() {
$scope.tasks.push($scope.title);
}
$scope.delete = function() {
$scope.tasks.splice(this.$index, 1);
}
})
</script>
<div ng-app="todoApp" ng-controller="todoController">
<form ng-submit="add()">
<input ng-model="title"><button>Add</button>
</form>
<ul>
<li ng-repeat="t in tasks track by $index">{{ t }} <button ng-click="delete()">x</button></li>
</ul>
</div>
Try!

Published on 2016-02-28