Создать класс инъекции (конструктор)
Я новичок в AngularJS, и я только начинаю понимать понятия и различия factory
, service
и controller
. Насколько я понимаю, a factory
используется для возврата объекта значения, который может быть введен. Большинство примеров, которые я видел, делают примерно так:
angular.module('module.factories', function() {
factory('FactoryObject', function() {
return {
someFunction: function(someParam) {};
someOtherFunction: function(someOtherParam) {});
};
});
});
В моем controller
, я хочу иметь возможность использовать этот объект, но я хотел бы инициализировать/инстанцировать его в контроллере, поскольку он может быть повторно инициализирован в зависимости от событий/действий в контроллере. Поэтому мне было интересно, могу ли я вместо этого вернуть конструкторную функцию в factory?
angular.module('module.factories', function() {
factory('FactoryObject', function() {
function FactoryObject(initParam) {
}
FactoryObject.prototype.someFunction = function() {};
return FactoryObject;
});
});
Является ли это подходящим шаблоном для angular factory? Или это просто "overkill" для использования factory для пользовательского объекта, подобного этому? Должен ли я просто включить его в файл js библиотеки и вместо этого ссылаться на него? Одно из преимуществ его размещения в factory заключается в том, что будет легко издеваться над ним в тесте, поскольку оно будет введено там, где оно используется. Существуют ли какие-либо другие механизмы в angular, которые могут быть использованы вместо этого?
Ответы
Ответ 1
Вы совершенно правы, это способ создания инъекционных "классов" (конструкторов). Однако использование factory
необходимо только тогда, когда вам нужно вводить другие вещи, которые будут использоваться вашим классом:
.factory('Class', ['$q', function ($q) {
function Class () {}
Class.prototype = {
constructor: Class,
doSomeAsyncAction: function () {
return $q(function (resolve, reject) {
// ...
});
},
// ...
};
return Class;
})
Если вы создаете полностью независимый класс (например, некоторую структуру данных), вы можете просто использовать constant
, чтобы ваш класс был доступен даже у поставщиков услуг:
(function (undefined) {
function Class () {}
Class.prototype = { ... };
angular.module(...)
.constant('Class', Class);
})();
Как побочный элемент, использование provider
не поможет вам в этом. Провайдеры служат совершенно другой цели и (среди прочего) возвращают функцию factory, которая затем используется _once_ в первой запрошенной инъекции, чтобы создать один экземпляр службы. Провайдеры используются для настройки этого экземпляра единой службы в фазе _config_ построения приложения (см. Документацию).
Ответ 2
У меня такая же проблема. Вот что я реализовал:
angular.module('foo', [])
.factory('Foo', ['$http', function($http) {
return function(a, b) {
this.arr = [];
this.a = a;
this.b = b;
this.random = Math.floor(Math.random()*11);
this.someFunc = function(c) {
this.arr.push(c);
};
};
}]);
Теперь я могу сделать:
var f1 = new Foo('A', 'B');
f1.random; // i.e. 0
f1.someFunc('z'); // only affects f1.arr
var f2 = new Foo('C', 'D');
f2.random; // i.e. 8
f2.someFunc('y'); // only affects f2.arr
Делает вещи более модульными. Надеюсь, что это поможет.
Ответ 3
У меня был тот же вопрос. Я нашел потрясающую статью о том, как настроить Object-oriented AngularJS Services. Здесь статья. Обратите внимание на примечание об использовании заводов, а не услуг. Он также охватывает расширение ваших объектов. Я нашел его очень простым в настройке, и он идеально сочетается с Angular, сохраняя Javascript простым и прямым.
Для служб Factory, которые являются одноточечными и не нуждаются в создании экземпляров, я использую подход объектного литерала, который имеет некоторые преимущества производительности.
Ответ 4
Вот как я решил проблему:
(function (myModule) {
'use strict';
myModule.service('myService', [
function() {
var serivce = this;
var obj = null;
service.func1 = function(a, b) {
}
service.func2 = function(c, d) {
. . .
return something;
}
var constructor = function(myObj) {
obj = myObj;
return service;
}
return constructor;
}
]);
}(angular.module("myModule")))
(function(myModule) {
'use strict';
myModule.controller('myController', [
'$scope', 'myService', function($scope, myService) {
var service = myService($scope.someObj);
$scope.someOtherObj = service.func2($scope.a, $scope.b);
}
]);
}(angular.module("myModule")))
Единственное, что возвращается службой, это конструктор, а затем служба возвращает остальную часть службы.