После примеров про 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
и показа их в виде списка.
<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>
Активация поля ввода нажатием 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-странице.
<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>