Разработка Web-приложений на Angular JS
Докладчик: Левицкий Борис
Software Architect, Softengi
Data Binding
Большинство темплейтных систем
Angular JS
Data Binding<div ng-app ng-init="qty=1;cost=2">
<b>Invoice:</b>
<div>
Quantity: <input type="number" ng-model="qty" required >
</div>
<div>
Costs: <input type="number" ng-model="cost" required >
</div>
<div>
<b>Total:</b> {{qty * cost | currency}}
</div></div>
Live Demo
Под капотом: Модель - Scope
Как работает Data-Binding
ng-click
$scope.$eval(): $rootScope.$digest(): loop through all child scopes:
$scope.$digest()
$scope.$digest(): process all watchers in loop
custom-code
Недостатки
● Достоинстваo “Чистая” модельo Выражения вплоть до использования функций в data binding’е
● Недостаткиo Нужно вызывать $scope.$apply(); для кода “извне”o Слишком большое количество watcher’ов могут существенно
замедлить производительность
Наследование Scope
Важно: Данные лучше хранить объедененными в один объект-модель, чем отдельными свойствами в scope.
Контроллер как модель<div ng-app ng-controller="MyCtrl as ctrl">
Hello, {{ctrl.name}}!
<button ng-click="ctrl.action()">Click</button></div>
Live Demo
Директивы
Фактически позволяют расширять возможности HTML
Пример: Angular JS Todo App Example
Важно: Директивы призваны расширять UI и не должны содержать бизнес логику или другой view-independent код.
Cоздание собственных директив
Примеры директив от Angular JS
ФильтрыПозволяют производить дополнительную обработку значений перед записью во View тем самым снимая отвественность за это с модели.
In HTML Template Binding
{{ filter_expression | filter : expression : comparator}}
In JavaScript
$filter('filter')(array, expression, comparator)
Пример кастомного фильтра
//Возвращает новый массив, где пропущенно указанное количество элементов в //исходном
массиве
module.filter('skip', [function () {
return function (arr, count) {
return arr ? arr.slice(count) : arr;
};
}])
//Использование
<tr data-ng-repeat="metric in Metrics | skip:pagination.getSkipCount() | limitTo: pagination.pageSize">
Валидация
ng-form - автоматически отражает состояние формы и её контроллов в виде модели внутри Scope
● Информация о валидности каждого поля или всей вормы сразу
● Список ошибок, связанных с каждым полем формы
● Понимает HTML5 валидационные атрибуты
Ng-Form Validation Live DemongModel Custom Validation Demo
View Independent CodeApplication Structure, Services
Структура Angularприложеня
Типы сервисов
● Constant● Value● Factory● Service● Provider
Constant, Value
Value - application-wide сервис-объект, который может быть инжектирован в инстансы и контроллеры.
Constant - application-wide сервис-объект, который может быть инжектирован в инстансы и контроллеры а также в функции конфигурации приложеня. Может быть изменен.
Factory
Позволяет создать Singleton объект доступный во всем приложении.
Live Demo
Service
function MyService() {}//Factoryapp.factory('MyService', function() { return new MyService();})//Equivalent Serviceapp.service('MyService', MyService)
Provider
Жизненный цикл приложения
● Config - этап конифигурации провайдеров. Только провайдеры и константы могут быть инжектированы.
● Run - этап инициализации приложения. Только инстансы и константы могут быть инжектированы. Доступен корневой скоуп приложения - $rootScope
Provider - factory, который позволяет выполнить кастомную конфигурацию на сonfig этапе
Live Demo
//Annotated injectionapp.controller('Ctrl1', function ($scope, myService) { … });//'Safe' annotated injection (RECOMMENDED)app.controller('Ctrl2', ['$scope', 'myService', function ($scope, myService) { … }]);//Explicit injectionfunction Ctrl3($scope, myService) { … }Ctrl3.$injector = ['$scope', 'myService'];app.controller('Ctrl3', Ctrl3);//Manual injectionvar $injector = angular.injector();
//Get instancevar service = $injector.get('serviceA');
//Invoke function with injections$injector.invoke(['serviceA', function(serviceA){}]);
Injector - Иньекция зависимостей
Стандартные сервисы Angular● $http - ajax запросы (использует промисы)
● $location - манипулиции с window.location
● $rootScope - корневая модель приложения
● $rootElement - корневой HTML элемент приложения
● $q - реализация промисов
● $log - логирование (можно отключать debug режим)● $cookies - работа с куками
Полный список сервисов
Организация структуры приложения
● Простая схема - по типу файлов● Модуальная схема - по модулям/подсистемам
Организация по типу файлов.\app
\partials - все view приложенияusers\edit.tpl.htmladmin\dashboard.html
\controllers - все контроллеры приложения\users\edit.js\admin\dashboard.js
\servicesservice1.jsservice2.js
.\app.js - конфигурация и инициализация всех модулей
.\routes.js - декларация роутинга для всех модулей
Недостатки простой схемы в больших приложениях
● Неудобно переключаться между view.tpl.html и controller.js файлами
● “Размазанность” подсистемы по различным папкам и файлам. Дублирование веток дерева:○ Views\..○ Controllers\..○ services\..○ routes.js○ app.js
Модульная структура.\app
\users\ - Подсистема “Пользователи” edit\edit.tpl.htmledit.ctrl.js
view\view.tpl.htmlview.ctrl.js
\admin\ - Подсистема “Администрирования”services\ - Специфичные сервисы подсистемы
adminService.jsdashboard\dashboard.tpl.htmldashboard.ctrl.js
\services\ - общие сервисы для всей системы dataService.jssecurityService.js
.\app.js - декларация модуля всего приложения, регистрация зависимостей на другие модули
Задача каждого модуля
● Конфигурация внутренних и внешних сервисов● Регистрация роутинга● Регистарция других компонентов
o Регистарция пунктов главного меню● Инциализация модуля
Демонстрация модульной структуры приложения Modern Security Technology Suite
$resource
Позволяет создать объект-инкапуслирующий основные запросы к REST сервисам на основе URL-шаблона
Article