angular.service vs angular.factory

后端 未结 9 2127
走了就别回头了
走了就别回头了 2020-11-22 02:50

I have seen both angular.factory() and angular.service() used to declare services; however, I cannot find angular.service anywhere in official documentation.

9条回答
  •  你的背包
    2020-11-22 03:17

      angular.service('myService', myServiceFunction);
      angular.factory('myFactory', myFactoryFunction);
    

    I had trouble wrapping my head around this concept until I put it to myself this way:

    Service: the function that you write will be new-ed:

      myInjectedService  <----  new myServiceFunction()
    

    Factory: the function (constructor) that you write will be invoked:

      myInjectedFactory  <---  myFactoryFunction()
    

    What you do with that is up to you, but there are some useful patterns...

    Such as writing a service function to expose a public API:

    function myServiceFunction() {
      this.awesomeApi = function(optional) {
        // calculate some stuff
        return awesomeListOfValues;
      }
    }
    ---------------------------------------------------------------------------------
    // Injected in your controller
    $scope.awesome = myInjectedService.awesomeApi();
    

    Or using a factory function to expose a public API:

    function myFactoryFunction() {
      var aPrivateVariable = "yay";
    
      function hello() {
        return "hello mars " + aPrivateVariable;
      }
      
      // expose a public API
      return {
        hello: hello
      };
    }
    ---------------------------------------------------------------------------------
    // Injected in your controller
    $scope.hello = myInjectedFactory.hello();
    

    Or using a factory function to return a constructor:

    function myFactoryFunction() {
        return function() {
            var a = 2;
            this.a2 = function() {
                return a*2;
            };
        };
    }
    ---------------------------------------------------------------------------------
    // Injected in your controller
    var myShinyNewObject = new myInjectedFactory();
    $scope.four = myShinyNewObject.a2();
    

    Which one to use?...

    You can accomplish the same thing with both. However, in some cases the factory gives you a little bit more flexibility to create an injectable with a simpler syntax. That's because while myInjectedService must always be an object, myInjectedFactory can be an object, a function reference, or any value at all. For example, if you wrote a service to create a constructor (as in the last example above), it would have to be instantiated like so:

    var myShinyNewObject = new myInjectedService.myFunction()
    

    which is arguably less desirable than this:

    var myShinyNewObject = new myInjectedFactory();
    

    (But you should be wary about using this type of pattern in the first place because new-ing objects in your controllers creates hard-to-track dependencies that are difficult to mock for testing. Better to have a service manage a collection of objects for you than use new() wily-nilly.)


    One more thing, they are all Singletons...

    Also keep in mind that in both cases, angular is helping you manage a singleton. Regardless of where or how many times you inject your service or function, you will get the same reference to the same object or function. (With the exception of when a factory simply returns a value like a number or string. In that case, you will always get the same value, but not a reference.)

提交回复
热议问题