TODO в AngularJS

ng-repeat push ng-click $index

После примеров про 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>

view

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

view

Related Pages

Учебник AngularJS

Author

Gabor Szabo (szabgab) Gabor Szabo