Внедрение зависимостей (Dependency Injection) в AngularJS
Пример использования внедрения зависимостей в AngularJS.
Обзор приложения Spring MVC + AngularJS + Bootstrap + HTML5
Используемые технологии и библиотеки
- Spring MVC 4.2.4.Release
- AngularJS 1.5.0
- IntelliJ IDEA 15.0.2
1. Описание задачи
Рассмотреть пример использования внедрения зависимостей в AnugularJS.
2. Структура проекта
Внедрение зависимостей рассматривается на странице angularDI.jsp. Внедряемые зависимости были добавлены в пакет resources\angularjs\dependencies (factory.js, provider.js, root.js, service.js)
3. Внедрение зависимостей в AngularJS
- AngularJS поддерживает модульную разработку и предоставляет возможность разделения приложения на слои.
- Приложения AngularJS начинаются с определения главного модуля.
- Модули могут быть заданы в различных js файлах.
- Модули могут быть внедрены в другие модули.
- Разработчики могут определять контроллеры, сервисы, фильтры, фабрики, директивы и т.п. в различных модулях.
- Различные модули можно импортировать с помощью <script src=’test.js’> </script>
3.1. Способы внедрения зависимостей
Существует несколько способов внедрения зависимостей в AngularJS.
- Использование массива с перечислением (рекомендуется).
- Использование свойства $inject.
- Непосредственно из имени параметра функции (существуют оговорки)
Итак рассмотрим по порядку. С помощью массива зависимости внедряются следующим образом:
1 2 3 |
someModule.controller('MyController', ['$scope', 'greeter', function($scope, greeter) { // ... }]); |
С помощью $inject:
1 2 3 4 5 |
var MyController = function($scope, greeter) { // ... } MyController.$inject = ['$scope', 'greeter']; someModule.controller('MyController', MyController); |
С помощью неявного внедрения (через функцию):
1 2 3 |
someModule.controller('MyController', function($scope, greeter) { // ... }); |
4. Применение внедрения зависимостей в AngularJS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!-- AngularJS myApp --> <spring:url value="/resources/angularjs/dependencies/root.js" var="myApp" /> <script src="${myApp}"></script> <!-- AngularJS service --> <spring:url value="/resources/angularjs/dependencies/service.js" var="service" /> <script src="${service}"></script> <!-- AngularJS factory --> <spring:url value="/resources/angularjs/dependencies/factory.js" var="factory" /> <script src="${factory}"></script> <!-- AngularJS provider --> <spring:url value="/resources/angularjs/dependencies/provider.js" var="provider" /> <script src="${provider}"></script> <div ng-app="myApp"> <h3>Пример внедрения зависимостей AngularJS</h3> <h4>AngularJS Factory:</h4> <div ng-controller="factoryController"> {{ angularVersion }} </div> <h4>Service controller:</h4> <div ng-controller="serviceController"> <button ng-click="serviceMethod()">service controller call</button> </div> <h4>AngularJS provider:</h4> <div ng-controller="providerController"> {{ rootName }} </div> <h4>AngularJS value:</h4> <div ng-controller="valueController"> someObject value module: {{ rootObject }} </div> </div> |
Сначала мы добавляем на страницу несколько javascript файлов, которые будут предоставлять нам определенный код, который мы будем внедрять в необходимые html элементы.
4.1. factory.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
//creates values or objects on demand angular.module("myApp") .value("someFactoryValue", "AngularJS framework") .factory("angularFactory", function(someFactoryValue) { var angularFactory = { 'angularVersion': someFactoryValue, 'siteName': 'javastudy.ru', getAngularVersion: function() { alert('Angular version is' + this.angularVersion); } }; return angularFactory; }) .controller("factoryController", function($scope, angularFactory) { alert(angularFactory.angularVersion); $scope.angularVersion = angularFactory.angularVersion; console.log(angularFactory.angularVersion); angularFactory.getAngularVersion(); }); |
Этот файл создает зависимости по требованию. После того как загрузка дойдет до вызова контроллера factoryController будет произведена инициализация переменных с помощью метода factory().
4.2. provider.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//configurable service factory angular.module("myApp") .constant("testConstant","constant value") .provider("configuredService", function() { var name = ''; this.setName = function(newName) { this.name = newName; }; this.$get = function() { var name = this.name; return { getName: function() { return "Java Spring MCV and AngularJS"; } } }; }) .config(function(configuredServiceProvider){ configuredServiceProvider.setName('provider name'); }) .controller("providerController", function($scope, configuredService) { $scope.rootName = configuredService.getName(); alert(configuredService.getName()); }); |
Провайдер это фабрика, настроенная особым образом. Провайдер ожидает функцию $get, которая будет внедрять другую часть приложения. Здесь в функции определяется переменная name и по запросу к $get будет возвращено значение Java Spring MCV and AngularJS.
4.3. root.js
1 2 3 4 5 6 7 8 9 10 11 12 |
angular.module("myApp", ['serviceModule']) .value("someObject", { objectName: "Mordor", objectValue: "Default City", getObjectDetails: function (){ return this.objectName + " is " + this.value; } }) .controller("valueController", function ($scope, someObject) { $scope.rootObject = someObject; }); |
Определяем некий root элемент (rootObject = someObject), который затем используется на html странице с помощью выражения {{rootObject}}.
4.4. service.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
//organise and share your code across the application //contains set of methods and provides communication across controllers //services are singleton instantiated only one for angularjs app angular.module("serviceModule", []) .service('TestService', function(){ this.function1 = function(p) { alert("function1"); }; this.function2 = function(p) { alert("function2 from service.js"); }; this.function3 = function(p) { alert("function3 from service.js"); }; this.serviceMethod = function(p) { alert("serviceMethod from service.js"); } }).controller("serviceDependency", function ($scope, TestService){ TestService.function1(); }).controller("serviceController", function($scope, TestService) { TestService.function2(); $scope.serviceMethod = function() { TestService.serviceMethod(''); } }); |
Здесь определяется вызов определенной функции с передачей параметра внутрь функции.
5. Запуск приложения
При загрузке страницы будут всплывать алерты с указанием внедренной зависимости. После этого мы увидим следующую страницу с данными.
Исходные коды
MVC_AngularJS_Html5 full project — полный проект Spring MVC + AngularJS + Bootstrap + HTML5.