Написание сервисов в Angular.js
В предыдущей статье мы оживили список транзакций и добавили возможность добавлять новые транзакции. Тем не менее, как мы видим в боковом меню нашего приложения, общая сумма денег никак не связана с транзакциями. На самом деле, это просто текст, прописанный в html коде.
В этой статье мы рассмотрим сервисные объекты, доступные в Angular.js. Мы будем использовать сервисы как единое место для доступа к нашим транзакциям, что позволит нам получить эти данные в разных контроллерах. Так же мы познакомимся с Dependency Injection в Angular.js.
В Angular.js доступен целый зоопарк различных типов сервисных объектов. Наиболее популярными из них являются factory
и service
. Каждый такой сервис является синглтоном, то есть существует всего один экземпляр конкретного сервиса. Это идеально вписывается в наши условия: единая точка доступа к транзакциям, доступная из любых контроллеров.
Сегодня мы будем использовать factory
, и скоро вы поймёте почему.
Начнём с добавления нового файла: src/components/transactions_store.service.js
со следующим содержимым:
// src/components/transactions_store.service.js
angular.module('ngmkdev').factory('TransactionsStore', function() {
return {
transactions: []
}
});
В отличии от контроллеров, с сервисами мы обладаем большей свободой в выборе имени. В данном случае TransactionsStore
имеет смысл, потому что данный сервис будет хранить все текущие транзакции.
Теперь нам необходимо соединить этот сервис с TransactionsCtrl
. В Angular.js используется паттерн Dependency Injection. Фреймворк умеет сам разрешать необходимые зависимости, разработчику необходимо только указать название компонента, который нужен другому компоненту приложения. Выглядит указание зависимостей следующим образом:
// src/app/main/transactions.controller.js
angular.module('ngmkdev').controller('TransactionsCtrl', function($scope, TransactionsStore) {
// ...
});
Теперь у нас есть доступ к нашему сервису из контроллера для транзакций. Так как мы использовали factory, то при вызове TransactionsStore
будет вызвана функция из определения этого сервиса, а значит мы можем легко получить все транзакции и записать их атрибуты контроллера следующим образом:
// src/app/main/transactions.controller.js
angular.module('ngmkdev').controller('TransactionsCtrl', function($scope, TransactionsStore) {
this.transactions = TransactionsStore.transactions;
// ...
});
Обратите внимание, что остальная часть кода остаётся неизменной – Angular.js сам позаботится о связи атрибута контроллера transactions
и обновлением сервиса.
Теперь убедимся в работоспособности нашего сервиса. Проделаем ряд уже знакомых операций:
Добавим новый контроллер src/app/main/navigation.controller.js
, отвечающий за боковое меню в приложении:
// src/app/main/navigation.controller.js
angular.module('ngmkdev').controller('NavigationCtrl', function(TransactionsStore) {
this.transactions = TransactionsStore.transactions;
});
Определим его на боковом меню и выведем число транзакции в скобках после пункта Транзакции:
<!-- src/index.html -->
<!-- ... -->
<div class="col-xs-2" ng-controller="NavigationCtrl as navigation_ctrl">
<h2>Деньги</h2>
<h3 class="money-ok">
500.0
</h3>
<ul class="nav nav-pills nav-stacked">
<li>
<a href="#">
<i class="glyphicon glyphicon-th-list"></i>
Транзакции <span class="badge">{{navigation_ctrl.transactions.length}}</span>
</a>
</li>
<li>
<a href="#"><i class="glyphicon glyphicon-tasks"></i> Настройки</a>
</li>
</ul>
</div>
<!-- ... -->
Перезагрузим страницу в браузере (если gulp ещё не сделал этого) и попробуем добавить транзакцию. Помимо обновления таблицы с транзакциями автоматически обновляется и счётчик транзакций в боковом меню.
Коммит со всеми изменениями, как всегда, в репозитории проекта на GitHub: 6d661c0
Домашняя работа (подсказки):
- Замените статичную сумму транзакций в боковом меню на настоящую.
- Спрячьте таблицу если у пользователя нет ни одной транзакции