[angularjs] 서비스 대 팩토리에 대한 혼란

알다시피, 공장 내부에서는 컨트롤러에 주입되는 물체를 반환합니다. 서비스 내부에서 나는 this아무것도 사용 하지 않고 객체를 사용 하고 있습니다.

나는 서비스가 항상 singleton 이라고 가정하고 모든 컨트롤러에 새로운 팩토리 객체 가 주입 된다고 가정했다 . 그러나 팩토리 객체도 싱글 톤입니까?

설명하는 예제 코드 :

var factories = angular.module('app.factories', []);
var app = angular.module('app',  ['ngResource', 'app.factories']);

factories.factory('User', function () {
  return {
    first: 'John',
    last: 'Doe'
  };
});

app.controller('ACtrl', function($scope, User) {
  $scope.user = User;
});

app.controller('BCtrl', function($scope, User) {
  $scope.user = User;
});

변경하는 경우 user.firstACtrl그것을 밝혀 user.first에서이 BCtrl예는,도 변경됩니다 User싱글인가?

내 가정은 공장이있는 컨트롤러에 새 인스턴스가 주입되었다는 것입니까?



답변

모든 각도 서비스는 싱글 톤입니다 .

문서 ( 싱글 톤으로 서비스 참조 ) : https://docs.angularjs.org/guide/services

마지막으로 모든 Angular 서비스는 응용 프로그램 싱글 톤임을 인식하는 것이 중요합니다. 이는 인젝터 당 지정된 서비스 인스턴스가 하나만 있음을 의미합니다.

기본적으로 서비스와 공장의 차이점은 다음과 같습니다.

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

  // service is just a constructor function
  // that will be called with 'new'

  this.sayHello = function(name) {
     return "Hi " + name + "!";
  };
});

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

  // factory returns an object
  // you can run some code before

  return {
    sayHello : function(name) {
      return "Hi " + name + "!";
    }
  }
});

$ provide에 대한이 프레젠테이션을 확인하십시오 : http://slides.wesalvaro.com/20121113/#/

이 슬라이드는 AngularJs 모임 중 하나에서 사용되었습니다 : http://blog.angularjs.org/2012/11/more-angularjs-meetup-videos.html


답변

나를 위해 계시는 그들이 모두 같은 방식으로 작동한다는 것을 깨달았을 때 나타났습니다. 무언가를 한 번 실행하고 얻은 값을 저장 한 다음 Dependency Injection을 통해 참조 할 때 동일한 저장된 값 을 기침합니다 .

우리가 가지고 있다고합시다.

app.factory('a', fn);
app.service('b', fn);
app.provider('c', fn);

세 가지의 차이점은 다음과 같습니다.

  1. a저장된 값은 running fn에서 나온다 .fn()
  2. b저장된 값은 newing 에서 가져옵니다 fn. 즉,new fn()
  3. c저장된 값은 new먼저을 호출 하여 인스턴스를 fn가져온 다음 $get인스턴스 의 메소드 를 실행 하여 발생합니다.

즉, 각도 내부에 캐시 객체와 같은 것이 있는데, 각 분사의 값은 처음 분사 될 때 한 번만 할당되며 어디서 :

cache.a = fn()
cache.b = new fn()
cache.c = (new fn()).$get()

이것이 우리 this가 서비스에서 사용 this.$get하고 공급자를 정의하는 이유 입니다.

도움이 되었기를 바랍니다.


답변

라이브 예

“hello world”예

factory/ service/ provider:

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

//service style, probably the simplest one
myApp.service('helloWorldFromService', function() {
    this.sayHello = function() {
        return "Hello, World!"
    };
});

//factory style, more involved but more sophisticated
myApp.factory('helloWorldFromFactory', function() {
    return {
        sayHello: function() {
            return "Hello, World!"
        }
    };
});

//provider style, full blown, configurable version     
myApp.provider('helloWorld', function() {
    // In the provider function, you cannot inject any
    // service or factory. This can only be done at the
    // "$get" method.

    this.name = 'Default';

    this.$get = function() {
        var name = this.name;
        return {
            sayHello: function() {
                return "Hello, " + name + "!"
            }
        }
    };

    this.setName = function(name) {
        this.name = name;
    };
});

//hey, we can configure a provider!            
myApp.config(function(helloWorldProvider){
    helloWorldProvider.setName('World');
});


function MyCtrl($scope, helloWorld, helloWorldFromFactory, helloWorldFromService) {

    $scope.hellos = [
        helloWorld.sayHello(),
        helloWorldFromFactory.sayHello(),
        helloWorldFromService.sayHello()];
}​


답변

당신이 돌아갈 수 있도록 생성자 함수를 반환하는 방법도있다 newable 과 같이 공장에서 클래스 :

function MyObjectWithParam($rootScope, name) {
  this.$rootScope = $rootScope;
  this.name = name;
}
MyObjectWithParam.prototype.getText = function () {
  return this.name;
};

App.factory('MyObjectWithParam', function ($injector) {
  return function(name) {
    return $injector.instantiate(MyObjectWithParam,{ name: name });
  };
}); 

따라서 MyObjectWithParam을 사용하는 컨트롤러에서이를 수행 할 수 있습니다.

var obj = new MyObjectWithParam("hello"),

전체 예를 보려면 여기를 참조하십시오 :
http://plnkr.co/edit/GKnhIN?p=preview

그리고 여기에 토론 된 Google 그룹 페이지 :

https://groups.google.com/forum/#!msg/angular/56sdORWEoqg/b8hdPskxZXsJ


답변

주요 차이점은 다음과 같습니다.

서비스

통사론: module.service( 'serviceName', function );

결과 : serviceName을 주사 가능한 인수로 선언하면에 전달 된 함수인스턴스 가 제공 됩니다 module.service.

사용법 : 주입 된 함수 참조에 단순히 ()를 추가하여 호출하는 데 유용한 유틸리티 함수공유하는 데 유용 할 수 있습니다 . 함께 injectedArg.call( this )또는 유사 하게 실행할 수 있습니다 .

공장

통사론: module.factory( 'factoryName', function );

결과 : factoryName을 주입 가능한 인수로 선언하면에 전달 된 함수 참조를 호출하여 리턴되는 값이 제공 됩니다 module.factory.

사용법 : 인스턴스를 만들기 위해 새로 만들 수 있는 ‘클래스’ 기능 을 반환하는 데 유용 할 수 있습니다 .

또한 서비스 대 팩토리에 대해 혼란스러워하는 Stackoverflow에 대한 AngularJS 문서 및 유사한 질문을 확인하십시오 .

다음은 services 및 factory를 사용하는 예 입니다. AngularJS 서비스와 팩토리 에 대해 자세히 읽어보십시오 .


답변

첫 번째 대답에 덧붙여서, .service ()는 코드를 더 객체 지향 스타일 (C # / Java)로 작성한 사람들 (이 키워드를 사용하고 프로토 타입 / 생성자 함수를 통해 객체를 인스턴스화하는 사람들)을위한 것이라고 생각합니다.

팩토리는 자바 스크립트 / 기능적 스타일의 코딩에 더 자연스러운 코드를 작성하는 개발자를위한 것입니다.

angular.js 내부의 .service 및 .factory 메소드의 소스 코드를 살펴보십시오. 내부적으로 모두 제공자 메소드를 호출합니다.

  function provider(name, provider_) {
    if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
    }
    if (!provider_.$get) {
      throw Error('Provider ' + name + ' must define $get factory method.');
    }
    return providerCache[name + providerSuffix] = provider_;
  }

  function factory(name, factoryFn) { \
    return provider(name, { $get: factoryFn });
  }

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


답변

아주 간단하게 :

.service-등록 된 함수는 생성자 (일명 ‘신규’)로 호출됩니다.

.factory-등록 된 함수는 간단한 함수로 호출됩니다.

둘 다 한 번 호출되어 단일 객체가 생성되어 앱의 다른 구성 요소에 주입됩니다.