Подтвердить что ты не робот

Создать класс инъекции (конструктор)

Я новичок в 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, которые могут быть использованы вместо этого?

4b9b3361

Ответ 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")))

Единственное, что возвращается службой, это конструктор, а затем служба возвращает остальную часть службы.