zoukankan      html  css  js  c++  java
  • [译]AngularJS Service vs Factory

    原文: http://blog.thoughtram.io/angular/2015/07/07/service-vs-factory-once-and-for-all.html

    Service和Factory有什么不同,我应该使用哪个? 

    这篇文章将讲解service和factory的不同之处,为什么我们喜欢service多过于factory.

    Service和Factory的不同之处

    在AngularJS中service和factory有什么不同? 我们可以这样定义一个service:

    app.service('MyService', function () {
      this.sayHello = function () {
        console.log('hello');
      };
    });
    

    .service() 是我们module的一个方法。 有两个参数,第一个参数是服务名,第二个参数是一个function. 可以把Service注入到其他的component中,如controller, directive, filters. 注入方法如下:

    app.controller('AppController', function (MyService) {
      MyService.sayHello(); // logs 'hello'
    });
    

    好了,看看factory是如何做同样的事情的:

    app.factory('MyService', function () {
      return {
        sayHello: function () {
          console.log('hello');
        };
      }
    });
    

     .factory() 同样是我们module的一个方法,有两个参数,第一个是factory名,第二个是一个function. 同样factory也可以注入到其他components中. 那么他的不同之处在哪呢?

    可以看到在factory中我们没有使用 this , 而是返回一个对象字面量. 为什么这样?因为,service是一个构造函数factory不是. 所以我们在factory的funtion中要显示的返回一个对象.

    来看看AngularJS的源代码中的factory函数是怎样的:

    function factory(name, factoryFn, enforce) {
      return provider(name, {
        $get: enforce !== false ? enforceReturnValue(name, factoryFn) : factoryFn
      });
    }
    

    factory接收一个name, 和factory函数,返回一个同名的provider, $get 是我们的factory函数. 当你获取一个注入,会调用$get()方法向相应的provider请求一个service的实例. 这就是为什么创建provider的时候需要有$get()方法.

    换而言之, 当注入MyService时, 后面究竟发生了什么呢:

    MyServiceProvider.$get(); // 返回service的实例
    

    现在看看service函数在AngularJS的源代码中是怎么样的:

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

    从代码中看得出来,当调用service()的时候实际上最后调用了factory(). 但是没有直接把service的构造函数传给factory. 而是传递了一个依赖injector的函数,通过这个injector去实例化. 简单的说: service调用了预定义的factory, 最后调用相应的provider的$get()方法. $injector.instantiate() 方法最终调用Object.create(),参数为构造函数. 这就是为什么我们要在service里面使用this.

    不论我么使用 service() 还是 factory(), 最终都是一个factory,然后这个factory去调用provider. 

    使用哪一个?

    “serivce和factory的不同如下:”

    app.service('myService', function() {
    
      // service是一个构造函数
    
      this.sayHello = function(name) {
         return "Hi " + name + "!";
      };
    });
    
    app.factory('myFactory', function() {
    
      // factory返回一个对象
    
      return {
        sayHello : function(name) {
          return "Hi " + name + "!";
        }
      }
    });
    

    是的service是一个构造函数, 然后我们一样可以在这个构造函数中返回对象字面量. 事实上, 在javascript中构造函数可以返回任何你想返回的东西. 所以我们把service写得和factory一样:

    app.service('MyService', function () {
    
      // 我们可以在这加入其它的代码
      return {
        sayHello: function () {
          console.log('hello');
        };
      }
    });
    

    现在factory和service的写法已经一样了. 问题是: 我们该使用哪一个呢?

    Service能让我们使用ES6的class

    在ES6中我们可以这样定义service:

    class MyService {
      sayHello() {
        console.log('hello');
      }
    }
    
    app.service('MyService', MyService);
    

    ES6 class和ES5中的构造函数是一回事.

  • 相关阅读:
    Laravel入坑指南(5)——请求与响应
    Laravel入坑指南(4)——数据库(Mysql)
    CentOS7 开机网卡加载失败
    个人CKeditor的config.js配置
    取消ie浏览器edge浏览器输入框右边的叉和眼睛
    angularjs中ckeditor的destroy问题
    angular js ckeditor directive示例代码
    建立没有文件名的文件
    设置ckeditor文本框的宽度为百分比自适应
    js中遍历删除数组中的项(项目中遇到的问题解决)
  • 原文地址:https://www.cnblogs.com/irocker/p/4672499.html
Copyright © 2011-2022 走看看