AngularJS: фабрика и сервис?

РЕДАКТИРОВАТЬ Январь 2016: Поскольку это все еще привлекает внимание. С тех пор, как я спросил об этом, я завершил несколько проектов AngularJS, и для тех, кого я в основном использовал factory, построил объект и вернул объект в конце. Мои утверждения ниже все еще верны, как бы то ни было.

РЕДАКТИРОВАТЬ: я думаю, что я, наконец, понимаю главное различие между ними, и у меня есть пример кода для демонстрации. Я также думаю, что этот вопрос отличается от предложенного дубликата. Дубликат говорит, что сервис не является инстанцируемым, но если вы настроите его, как я продемонстрировал ниже, это действительно так. Сервис может быть настроен так же, как на заводе. Я также предоставлю код, показывающий, где на заводе происходит сбой в обслуживании, что, похоже, не дает никакой другой ответ.

Если я настрою VaderService так (например, как сервис):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() {
    this.speak = function (name) {
        return 'Join the dark side ' + name;
    }
});

Тогда в моем контроллере я могу сделать это:

module.controller('StarWarsController', function($scope, VaderService) {
    $scope.luke = VaderService.speak('luke');   
});

С помощью сервиса создается экземпляр VaderService, введенный в контроллер, поэтому я могу просто вызвать VaderService.speak, однако, если я изменю VaderService на module.factory, код в контроллере больше не будет работать, и в этом главное отличие, С фабрикой VaderService, внедренный в контроллер, не создается, поэтому вам нужно возвращать объект при настройке фабрики (см. Мой пример в вопросе).

Тем не менее, вы можете настроить сервис точно так же, как вы можете настроить фабрику (в IE она возвращает объект), и сервис ведет себя точно так же, как фабрика

Учитывая эту информацию, я не вижу причин использовать фабрику над обслуживанием, обслуживание может сделать все, что может фабрика, и даже больше.

Оригинальный вопрос ниже.


Я знаю, что об этом спрашивали много раз, но я действительно не вижу никакой функциональной разницы между фабриками и службами. Я читал этот учебник: http://blogs.clevertech.biz/startupblog/angularjs-factory-service-provider

И это, кажется, дает достаточно хорошее объяснение, однако я настроил свое приложение следующим образом:

index.html

<!DOCTYPE html>
<html>
    <head>
    <title>My App</title>
    <script src="lib/angular/angular.js"></script>
    <script type="text/javascript" src="js/controllers.js"></script>
    <script type="text/javascript" src="js/VaderService.js"></script>
    <script type="text/javascript" src="js/app.js"></script>
    </head>

    <body ng-app="MyApp"> 
        <table ng-controller="StarWarsController">
            <tbody>
            <tr><td>{{luke}}</td></tr>
            </tbody>
        </table>
    </body>
</html>

app.js:

angular.module('MyApp', [
  'MyApp.services',
  'MyApp.controllers'
]);

controllers.js:

var module = angular.module('MyApp.controllers', []);

module.controller('StarWarsController', function($scope, VaderService) {
    var luke = new VaderService('luke');
    $scope.luke = luke.speak();
});

VaderService.js

var module = angular.module('MyApp.services', []);

module.factory('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Затем, когда я загружаю index.html, я вижу "Присоединяйся к темной стороне, Люк", отлично. Точно так, как и ожидалось. Однако, если я изменю VaderService.js на этот (обратите внимание на module.service вместо module.factory):

var module = angular.module('MyApp.services', []);

module.service('VaderService', function() {
    var VaderClass = function(padawan) {
        this.name = padawan;
        this.speak = function () {
            return 'Join the dark side ' + this.name;
        }
    }

    return VaderClass;
});

Затем перезагрузите index.html (я удостоверился, что очистил кеш и сделал полную перезагрузку). Он работает точно так же, как и с module.factory. Так в чем же реальная функциональная разница между этими двумя?

4 ответа

Решение

Сервис против Фабрики


Разница между фабрикой и обслуживанием так же, как разница между функцией и объектом

Фабрика Провайдер

  • Дает нам возвращаемое значение функции т.е. Вы просто создаете объект, добавляете к нему свойства, а затем возвращаете тот же объект. Когда вы передаете этот сервис в свой контроллер, эти свойства объекта теперь будут доступны в этом контроллере через вашу фабрику. (Гипотетический сценарий)

  • Синглтон и будет создан только один раз

  • Многоразовые компоненты

  • Фабрика - отличный способ общения между контроллерами, например, обмен данными.

  • Можно использовать другие зависимости

  • Обычно используется, когда экземпляр службы требует сложной логики создания

  • Не может быть введен в .config() функция.

  • Используется для неконфигурируемых сервисов

  • Если вы используете объект, вы можете использовать поставщика фабрики.

  • Синтаксис: module.factory('factoryName', function);

Поставщик услуг

  • Дает нам экземпляр функции (объекта)- вы просто создаете экземпляр с ключевым словом "new", и вы добавляете свойства к "this", и сервис возвращает "this". Когда вы передаете сервис в свой контроллер, эти свойства "Это" теперь будет доступно на этом контроллере через ваш сервис. (Гипотетический сценарий)

  • Синглтон и будет создан только один раз

  • Многоразовые компоненты

  • Сервисы используются для связи между контроллерами для обмена данными

  • Вы можете добавить свойства и функции к объекту службы, используя this ключевое слово

  • Зависимости вводятся как аргументы конструктора

  • Используется для простой логики создания

  • Не может быть введен в .config() функция.

  • Если вы используете класс, вы можете использовать поставщика услуг

  • Синтаксис: module.service(‘serviceName’, function);

Образец Демо

В приведенном ниже примере у меня есть определение MyService а также MyFactory, Обратите внимание, как в .service Я создал сервисные методы, используя this.methodname. В .factory Я создал фабричный объект и назначил ему методы.

AngularJS.service


module.service('MyService', function() {

    this.method1 = function() {
            //..method1 logic
        }

    this.method2 = function() {
            //..method2 logic
        }
});

AngularJS.factory


module.factory('MyFactory', function() {

    var factory = {}; 

    factory.method1 = function() {
            //..method1 logic
        }

    factory.method2 = function() {
            //..method2 logic
        }

    return factory;
});

Также посмотрите на эти красивые вещи

Смущен сервисом против фабрики

AngularJS Фабрика, Сервис и Поставщик

Angular.js: сервис против провайдера против фабрики?

Factory а также Service это просто обертка provider,

завод

Factory может вернуть все, что может быть class(constructor function), instance of class, string, number или же boolean, Если вы вернете constructor функция, вы можете создать экземпляр в вашем контроллере.

 myApp.factory('myFactory', function () {

  // any logic here..

  // Return any thing. Here it is object
  return {
    name: 'Joe'
  }
}

обслуживание

Сервис не должен ничего возвращать. Но вы должны назначить все в this переменная. Потому что служба создаст экземпляр по умолчанию и будет использовать его как базовый объект.

myApp.service('myService', function () {

  // any logic here..

  this.name = 'Joe';
}

Фактический код angularjs за сервисом

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
        return $injector.instantiate(constructor);
    }]);
}

Это просто обертка вокруг factory, Если вы вернете что-то из serviceто будет вести себя как Factory,

IMPORTANT: Возвращаемый результат от Factory и Service будет кешем и будет возвращен для всех контроллеров.

Когда я должен их использовать?

Factory в большинстве случаев предпочтительнее. Может использоваться, когда у вас есть constructor функция, которая должна быть реализована в разных контроллерах.

Service это своего рода Singleton Объект. Возврат Объекта из Сервиса будет одинаковым для всех контроллеров. Его можно использовать, когда вы хотите иметь один объект для всего приложения. Например: аутентифицированные данные пользователя.

Для дальнейшего понимания прочитайте

http://iffycan.blogspot.in/2013/05/angular-service-or-factory.html

http://viralpatel.net/blogs/angularjs-service-factory-tutorial/

  • Если вы используете сервис, вы получите экземпляр функции (ключевое слово "this").
  • Если вы используете фабрику, вы получите возвращаемое значение, вызвав ссылку на функцию (оператор возврата в фабрике)

Фабрика и Сервис - наиболее часто используемые рецепты. Единственное различие между ними заключается в том, что рецепт Service лучше работает для объектов пользовательского типа, тогда как Factory может создавать примитивы и функции JavaScript.

Ссылка

$ предоставить услугу

Технически это одно и то же, на самом деле это разные обозначения использования provider функция $provide сервис.

  • Если вы используете класс: вы можете использовать служебную нотацию.
  • Если вы используете объект: вы можете использовать фабричную нотацию.

Единственная разница между service и factory примечание, что сервис является новым, а завод нет. Но для всего остального они оба выглядят, пахнут и ведут себя одинаково. Опять же, это просто сокращение для функции $provide.provider.

// Factory

angular.module('myApp').factory('myFactory', function() {

  var _myPrivateValue = 123;

  return {
    privateValue: function() { return _myPrivateValue; }
  };

});

// Service

function MyService() {
  this._myPrivateValue = 123;
}

MyService.prototype.privateValue = function() {
  return this._myPrivateValue;
};

angular.module('myApp').service('MyService', MyService);
Другие вопросы по тегам