AngularJS实战笔记我爱编程

Angular中的服务

2016-08-02  本文已影响1658人  阿振_sc

在Angular中,服务的本质是一些和控制器捆绑在一起的可替换的对象,通过这些对象提供了在应用的整个生命周期都存有数据的方法,当重载或刷新页面时,数据不会被清除,而且还与加载之前保持一致。

Angular服务介绍

在Angular中服务是一种单例对象。服务主要的功能是为实现应用的功能提供数据和对象。它又可以分为内置服务和自定义服务

内置服务

Angular提供了很多内置服务,如$scope$http$window$location等。

html:

<div ng-controller="MyController">
  <div>当前的地址是: {{url}}</div>
  <button ng-click="onclick()">显示地址</button>
</div>
var myapp = angular.module('MyApp', []);
myapp.controller('MyController', ['$scope', function($scope){
  $scope.onclick = function () {
    $scope.url = $location.absUrl();
  }
}])

$location服务除了包含absUrl()方法外,还有search()path()等方法。同时它还提供了$locationChangeStart$locationChangeSuccess方法

自定义服务

自定义服务有两种方法,一是使用内置的$provider服务,另一种是调用模块(Module)中的服务注册方法,如factoryserviceconstantvalue等方法

html:

<div ng-controller="myCtrl">
  <div>服务返回的值:
    <span>{{info('name')}}</span>
    <span>{{info('sex')}}</span>
    <span>{{info('score')}}</span>
  </div>
</div>

javascript:

var app = angular.module('myApp', []);
  app.factory('$output', function () {
    var stu = {
      name: '张三',
      sex: '男',
      score: 60
    }
    return stu;
  });
  app.controller('myCtrl', ['$scope', '$output', function ($scope, $output) {
    $scope.info = function (n) {
      for (_n in $output) {
        if (_n == n) {
          return ($output[_n]);
        }
      }
    }
  }]);

创建Angular服务

在Angular中创建自定义服务,只需要先构建一个模块(Module),然后在构建过程中调用内置的$provide服务,通过该服务的工厂函数来创建属于自己的Angular服务。除此之外,还可以调用模块中的factoryserviceconstantvalue方法来创建。

使用factory方法自定义服务

在Angular中,最常用的创建自定义服务的,就是factory方法了

app.factory(name, fn);

html:

<div ng-controller="MyController">
  <div>{{str('我是factory返回的内容')}}</div>
  <div>{{name(1)}}</div>
</div>

javascript:

var myapp = angular.module('MyApp', []);
myapp.factory('outfun', function () {
  return {
    str: function (s) {
      return s;
    }
  }
});
myapp.factory('outarr', function () {
  return ['张三', '李四', '王五'];
});
myapp.controller('MyController', function ($scope, outfun, outarr) {
  $scope.str = function (n) {
    return outfun.str(n);
  }
  $scope.name = function (n) {
    return outarr[n];
  }
});

使用service方法自定义服务

使用service方法也可以自定义服务,与factory不同的是,它可以接受一个构造函数

app.service(name, fn)

其中,fn为构造函数,当注入该服务时,通过该函数并使用new关键字来实例化服务对象

html:

<div ng-controller="MyController">
  <div class="show">姓名: {{name}}</div>
  <div class="show">邮件: {{email}}</div>
  <div class="show">{{title}}</div>
  <button ng-click="say()">主题</button>
</div>

javascript:

var myapp = angular.module('MyApp', []);
  myapp.service('student', function () {
    this.name = 'Kaindy',
    this.email = 'kaindy7633@163.com',
    this.say = function () {
      return 'Hello, Angular!';
    }
  });
  myapp.controller('MyController', ['$scope', 'student', function ($scope, student){
    $scope.name = student.name;
    $scope.email = student.email;
    $scope.say = function () {
      $scope.title = student.say();
    }
  }]);

使用constant和value方法自定义服务

使用constantvalue方法创建服务,常用于返回一个常量。

app.constant(name, value)
app.value(name, value)

html:

<div ng-controller="MyController">
  <div class="show">图书ISBN号: {{BOOK}}</div>
  <div class="show">美元兑换价: {{USD}}</div>
</div>

javascript:

var myapp = angular.module('MyApp', []);
myapp.constant('$ISBN', {
    BOOK: '9898733238'
});
myapp.value('$RATE', {
    USD: 614.28
});
myapp.controller('MyController', function($scope, $ISBN, $RATE){
    var n = 600;
    angular.extend($RATE, {USD: n});
    $scope.BOOK = $ISBN.BOOK;
    $scope.USD = $RATE.USD;
})

管理服务的依赖

添加自定义服务依赖项方法

我们在自定义服务时,会添加其他各类对象或服务,有下面三种方式:

(1) 隐式声明

在参数中直接调用,但这种方式在代码压缩时注入的对象可能会失效

app.factory('ServiceName', function(dep1, dep2) {})

(2) 调用$inject属性

将需要注入的服务对象包装成一个数组,作为$inject的属性值,但这种方式效率很低

var sf = function(dep1, dep2) {};
sf.$inject = ['dep1', 'dep2'];
app.factory('ServieceName', sf);

(3) 显式声明

在创建服务的函数中,添加一个数组,在数组中按顺序声明需要注入的服务或对象名称,这种方式既高效也不会丢失代码,推荐使用

app.factory('ServiceName', ['dep1', 'dep2', function(dep1, dep2) {} ])

html:

<div ng-controller="MyController">
  <div class="show">你选择的是:{{result}}</div>
  <button ng-click="confirm('你真的要删除这条记录吗?')">删除</button>
</div>

javascript:

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

myapp.service('notify', ['$window', function ($win) {
  return function (msg) {
    return $win.confirm(msg) ? '确定' : '取消';
  }
}]);

myapp.controller('MyController', ['$scope', 'notify', function ($scope, notify) {
  $scope.confirm = function (msg) {
    $scope.result = notify(msg);
  }
}]);

嵌套注入服务

在Angular中,有时需要将一个自定义的服务注入到另一个自定义的服务中,形成嵌套注入的形式,通常只需要将被注入的服务作为内置服务,采用显式声明的方式注入即可

html:

<div ng-controller="MyController">
  <button ng-click="ask(false, '你输入的内容不正确')">提示框</button>
  <button ng-click="ask(true, '你真的要删除这条记录吗?')">询问框</button>
</div>

javascript:

var myapp = angular.module('MyApp', []);
  // 使用factory定义confirm服务
  myapp.factory('confirm', ['$window', function ($win) {
    return function (msg) {
      $win.confirm(msg);
    }
  }]);
  // 将confirm服务显式的注入到notify服务中
  myapp.service('notify', ['$window', 'confirm', function ($win, con) {
    return function (t, msg) {
      return (t) ? con(msg) : $win.alert(msg);
    }
  }]);
  myapp.controller('MyController', ['$scope', 'notify', function ($scope, notify) {
    $scope.ask = function (t, msg) {
      notify(t, msg);
    }
  }])

添加服务的其他设置

创建好的服务一般比较复杂,如果后期需要修改,往往面临很高的风险,Angular为服务添加了一些设置项,如装饰器(decorator),可以在不修改原代码的情况下为服务添加其他功能

服务的装饰器

装饰器(decorator)是Angular中内置服务$provide所特有的一项设置函数,通过它可以拦截服务在实例化时创建的一些功能,并对原有功能进行优化和替代。

$provide.decorator('ServiceName', Fn)

示例代码:

<div ng-controller="MyController">
  <div class="show">姓名: {{stu.name}}</div>
  <div class="show">邮件: {{stu.email}}</div>
  <div class="show">主题: {{stu.title}}</div>
</div>
var myapp = angular.module('MyApp', []);
  // 使用工厂函数factory定义student服务
  myapp.factory('student', function () {
    return {
      name: 'Kaindy',
      email: 'kaindy7633@gmail.com'
    }
  });
  // 使用$provider的装饰器decorator为服务student扩展一个title属性
  myapp.config(function ($provide) {
    $provide.decorator('student', function ($delegate) {
      $delegate.title = 'Hello, Angular!';
      return $delegate;
    })
  });

  myapp.controller('MyController', function ($scope, student) {
    $scope.stu = student;
  });
上一篇下一篇

猜你喜欢

热点阅读