• AngularJS: Service v. Factory


    From: http://www.tuicool.com/articles/zumyQv

    In various AngularJS tutorials and documentation, the authors choose to useservice or factory but don't explain why you would use one or the other. Few mention that value and constant are also options.

    Let's see why you would use one over the other. We should also understand how providers work:

    provider

    Here's the source for the provider method:

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

    name is a string. provider_ can be one of three things:

    1. function

      If a function is passed in, the function is called with dependency injection and should return an object with a $get method.

    2. array

      An array will be treated like a function using Inline Annotation . It must also return an object with a $get method.

    3. object

      If an object is passed in, it is simply expected to have a $get method.

    Whatever the second arg to provider is, you eventually end up with an object that has a $get method. Here's an example showing what happens:

    // You can run this
    
    // Create a module
    var hippo = angular.module('hippo', []);
    
    // Register an object provider
    hippo.provider('awesome', {
        $get: function() {
            return 'awesome data';
        }
    });
    
    // Get the injector (this happens behind the scenes in angular apps)
    var injector = angular.injector(['hippo', 'ng']);
    
    // Call a function with dependency injection
    injector.invoke(function(awesome) {
        console.log('awesome == ' + awesome);
    });
    

    Once you understand providers you will see that factory , service , valueand constant are just convenience methods for making providers.

    factory

    Here's the source:

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

    So it lets you shorten the awesome provider creation code to this:

    hippo.factory('awesome', function() {
        return 'awesome data';
    })
    

    service

    Here's the source:

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

    So it lets you make a factory that will instantiate a "class". For example:

    var gandalf = angular.module('gandalf', []);
    
    function Gandalf() {
        this.color = 'grey';
    }
    Gandalf.prototype.comeBack = function() {
        this.color = 'white';
    }
    
    gandalf.service('gandalfService', Gandalf);
    
    var injector = angular.injector(['gandalf', 'ng']);
    
    injector.invoke(function(gandalfService) {
        console.log(gandalfService.color);
        gandalfService.comeBack()
        console.log(gandalfService.color);
    });
    

    The above code will instantiate Gandalf , but remember that everything that uses the service will get the same instance! (which is a good thing).

    value

    Here's the source:

    function value(name, value) {
        return factory(name, valueFn(value));
    }
    

    Using value would let you shorten the awesome provider to:

    hippo.value('awesome', 'awesome data');
    

    constant

    Here's the source

    function constant(name, value) {
        providerCache[name] = value;
        instanceCache[name] = value;
    }
    

    constant differs from value in that it's accessible during config. Here's how you use it:

    var joe = angular.module('joe', []);
    
    joe.constant('bobTheConstant', 'a value');
    joe.value('samTheValue', 'a different value');
    
    joe.config(function(bobTheConstant) {
        console.log(bobTheConstant);
    });
    
    joe.config(function(samTheValue) {
        console.log(samTheValue);
    });
    
    // This will fail with "Error: Unknown provider: samTheValue from joe"
    var injector = angular.injector(['joe', 'ng']);
    

    Read Module Loading & Dependencies in the Modules doc for more information on usage.

    In summary

    If you want your function to be called like a normal function, use factory . If you want your function to be instantiated with the new operator, use service . If you don't know the difference, use factory .

    This is the (great) documentation for each function in the AngularJS source:

    1. factory

      A short hand for configuring services if only `$get` method is required.

    2. service

      A short hand for registering service of given class.

    3. value

      A short hand for configuring services if the `$get` method is a constant.

    4. constant

      A constant value, but unlike {@link AUTO.$provide#value value} it can be injected into configuration function (other modules) and it is not interceptable by {@link AUTO.$provide#decorator decorator}.


  • 相关阅读:
    linux安装jdk(二)
    Java实现进程调度算法(一) FCFS(先来先服务)
    用Java Swing实现Freecell(空当接龙)
    windows主机开启MySQL慢查询日志
    CentOS LNMP 服务器安装配置详解
    shopex 网店系统 v4.8.5 安装图文教
    mysqldumpslow和mysqlsla分析mysql慢查询日志
    window下nginx配置
    PHP开发编码规范
    IIS+PHP+MySQL+Zend Guard Loader(ZendOptimizer)+phpMyAdmin环境配置图解(转)
  • 原文地址:https://www.cnblogs.com/puncha/p/3876846.html
Copyright © 2020-2023  润新知