• Service vs Factory vs provider的迷惑


    刚开始我很迷惑的,但是经过一段时间的项目,还有看大漠老师的东西,似乎明白了,他们的区别也就是  一个人喜欢吃面还是吃饭或者肯德基区别。目的就是填饱肚子!

    以下是它们在AngularJS源代码中的定义:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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函数,而后者又调用了provider函数。事实上,AngularJS也为一些值、常量和装饰提供额外的provider封装,而这些并没有导致类似的困惑,它们的文档都非常清晰。

    由于service仅仅是调用了factory函数,这有什么区别呢?线索在$injector.instantiate:在这个函数中,$injector在service的构造函数中创建了一个新的实例。

    以下是一个例子,展示了一个service和一个factory如何完成相同的事情:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var app = angular.module('app',[]);
     
    app.service('helloWorldService', function(){
        this.hello = function() {
            return "Hello World";
        };
    });
     
    app.factory('helloWorldFactory', function(){
        return {
            hello: function() {
                return "Hello World";
            }
        }
    });

    当helloWorldService或helloWorldFactory被注入到控制器中,它们都有一个hello方法,返回”hello world”。service的构造函数在声明时被实例化了一次,同时factory对象在每一次被注入时传递,但是仍然只有一个factory实例。所有的providers都是单例。

    既然能做相同的事,为什么需要两种不同的风格呢?相对于service,factory提供了更多的灵活性,因为它可以返回函数,这些函数之后可以被新建出来。这迎合了面向对象编程中工厂模式的概念,工厂可以是一个能够创建其他对象的对象。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    app.factory('helloFactory', function() {
        return function(name) {
            this.name = name;
     
            this.hello = function() {
                return "Hello " + this.name;
            };
        };
    });

    这里是一个控制器示例,使用了service和两个factory,helloFactory返回了一个函数,当新建对象时会设置name的值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    app.controller('helloCtrl', function($scope, helloWorldService, helloWorldFactory, helloFactory) {
        init = function() {
          helloWorldService.hello(); //'Hello World'
          helloWorldFactory.hello(); //'Hello World'
          new helloFactory('Readers').hello() //'Hello Readers'
        }
     
        init();
    });

    在初学时,最好只使用service。

    Factory在设计一个包含很多私有方法的类时也很有用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    app.factory('privateFactory', function(){
        var privateFunc = function(name) {
            return name.split("").reverse().join(""); //reverses the name
        };
     
        return {
            hello: function(name){
              return "Hello " + privateFunc(name);
            }
        };
    });

    通过这个例子,我们可以让privateFactory的公有API无法访问到privateFunc方法,这种模式在service中是可以做到的,但在factory中更容易。

  • 相关阅读:
    pcDuino无显示器刷机与使用
    pcDuino安装vnc进行远程控制
    pcDuino 刷系统-卡刷
    HDU 5441 2015长春站online1005(并查集)
    HYSBZ 2002 Bounce 弹飞绵羊(分块)
    HYSBZ 2243 染色 LCT学习
    HYSBZ 2049 Cave 洞穴勘测
    SPOJ 375 LCT学习
    HDU 4010 动态树LCT学习
    ZJOI2008 树的统计 树链剖分学习
  • 原文地址:https://www.cnblogs.com/GoodPingGe/p/4517511.html
Copyright © 2020-2023  润新知