AngularJs功用(七)--效劳

效劳 Service

效劳这个观点实在并不生疏,比方在Java语言中便有如许的观点,其作用就是对外供应某个特定的功用,如音讯效劳,菜单效劳等,是一个自力的模块。

angular的效劳是如许定义的:
Angular services are singletons objects or functions that carry out specific tasks common to web apps.

在Angular中,效劳的实质是一些和控制器绑缚在一起的一个单例对象或函数,对外供应特定的功用。经由过程这些对象供应了在运用的全部生命周期都存有数据的要领,当重载或革新页面时,数据不会被消灭,而且还与加载之前保持一致。即不管这个效劳被注入到任何处所,对象一直只要一个实例。

这与我们自身定义一个function然后在其他处所挪用差别,由于效劳被定义在一个模块中,所以其运用局限是能够被我们治理的。angular的防止全局变量污染认识异常强。

内置效劳

Angular供应了许多内置效劳,如$scope、$http、$window、$location等。

我们引见一下$location。(注重效劳是怎样注入控制器的,后边会有零丁模块引见angular的依靠注入)

猎取url的相干要领:

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

以’http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false’ 这个途径为例:

1.猎取当前完全的url途径:

$location.absUrl():

http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false

*2.猎取当前url途径(当前url#背面的内容,包含参数和哈希值–哈希值引见):

$location.url();

// /demandManager/view.html?orderId=10&projectId=42&mWin=false

*3.猎取当前url的子途径(也就是当前url#背面的内容,不包含参数):
$location.path()
// /demandManager/view.html

4.猎取当前url的协定(比方http,https)

$location.protocol()

// http

5.猎取当前url的主机名

$location.host()

// localhost

6.猎取当前url的端口

$location.port()

// 80 (这里就是wamp的默许端口号)

*7.猎取当前url的哈希值(hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部份)

$location.hash()

// null

*8.猎取当前url的参数的序列化json对象

$location.search()

// {‘orderId’:10,’projectId’:42,’mWin’:’false’}

修正url的相干要领:

于$location.search(),$location.url();,$location.path(),$location.hash(),这四种能够传入参数举行修正url,在这类状况下,函数的返回值都是$location自身:

1.修正url的子途径(也就是当前url#背面的内容,包含参数):

参数花样:字符串

$location.url('/demandCustomer/view.html?orderId=10&projectId=42&mWin=true');
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandCustomer/view.html?orderId=10&projectId=42&mWin=true

2.修正url的子途径部份(也就是当前url#背面的内容,不包含参数):

参数花样:字符串

$location.path('/demandCustomer/view.html');
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandCustomer/view.html?orderId=10&projectId=42&mWin=false 

3.修正url的哈希值部份

参数花样:字符串

$location.hash('#footer');
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false#footer  

4.修正url的参数部份(这是重点啊!!!!!!!!)

(1).传入两个参数,第一个参数的花样为字符串:

①第二个参数的花样也是字符串

第一个参数示意url参数的属性名,第二个参数是该属性名的属性值,假如是已有属性名,则修正,假如不是已有属性,则新增

$location.search('mWin','true')
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=true

②第二个参数的花样为数组,数组中的各个值也是字符串或许布尔值

第一个参数示意url参数的属性名,第二个参数是该属性名的值,有多少个值,url中就会顺次反复涌现多少个.以下:

$location.search('projectSearch',['book','home'])
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false&projectSearch=book&projectSearch=home

(2).传入两个参数,第一个参数为字符串,第二个参数为null:

第一个值示意url参数的属性名,假如是已有属性名,则删除该属性,假如不是已有属性,那就即是没悛改

$location.search('projectId',null)
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&mWin=false

(3).传入一个参数,花样为json对象:

直接用这个json对象里的键值对替换全部url的参数部份

①平常的键值对:

$location.search({orderId:11,projectId:45,mWin:true,projectSearch:'book'})
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=11&projectId=45&mWin=true&projectSearch=book

②属性值为一个数组:

$location.search({orderId:11,projectId:45,mWin:true,projectSearch:['book','home']})
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=11&projectId=45&mWin=true&projectSearch=book&projectSearch=home

(4).传入一个参数,花样为字符串:

直接用这个字符串替换全部url的参数部份(没有键值对,参数部份就是一个属性名)

$location.search('role')
//http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?role

不存入历史纪录

在上文的一切修正url的要领的时刻,每修正一次,url都会被存入历史纪录,能够运用退却按钮回到修正前的url,假如不想要这类结果,而仅仅是替换当前的纪录,能够运用:

$location.replace();

例子:

// 原url:
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false


$location.url('/demandCustomer/view.html?orderId=10&projectId=45&mWin=true');
// 修正一次后:
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandCustomer/view.html?orderId=10&projectId=45&mWin=true

// 按下退却回到原url:
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false
// 再按下行进回到修正后url:
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandCustomer/view.html?orderId=10&projectId=45&mWin=true

$location.path('/demandCustomer').replace();
// 修正第二次后挪用replace():
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandCustomer/view.html?orderId=10&projectId=42&mWin=false

// 按下退却,不会回到第二次修正前的url,而是回到第一次修正前的url
// http://39.106.222.235:8080/cds/personalCenter/index.html#/demandManager/view.html?orderId=10&projectId=42&mWin=false

监听途径跳转

Angular也能够监听途径的变化,这些事宜我们会在路由中做解说。(待增加)

http要求

$http是Angular内置的效劳,用于效劳向效劳器发送要求,运用相应效劳器传送过来的数据。
写法:

写法一
$http({
  method: 'GET', //能够改成POST
  url: '/someUrl'
}).then(function successCallback(response) {
// 要求胜利实行代码
  }, function errorCallback(response) {
// 要求失利实行代码
});

写法二
$http.get('/someUrl',config).then(successCallback, errorCallback); 
$http.get('/someUrl',{params:{"id":3}}).then(successCallback, errorCallback);
$http.post('/someUrl', data:{name:"aaa",id:"1",age:"20"},config).then(successCallback, errorCallback);

jsonp写法
$http({ 
  method: 'JSONP', 
  url: 'http://www.b.com/test.php?callback=JSON_CALLBACK'
}).success(function(response){ 
  console.log(response); 
}); 

$http.jsonp(
  'http://www.b.com/test.php?callback=JSON_CALLBACK'
).success(function (response){ 
  console.log(response); 
}); 
//这里要注重,跨域要求的url后一定要追加参数callback,而且callback的值是牢固的,即JSON_CALLBACK,不要去做任何修改

这里只做简朴引见,项目中我们运用的是基于$http的$resource效劳,$resource依靠于$http。建立一个resource对象的工场函数,能够让你平安的和RESFUL效劳端举行数据交互。
须要注入 ngResource 模块。一样会有零丁模块引见。这里是衔接(待增加)。

延时器与计时器

J是中的setTimeout()和setInterval()这个人人一定不会生疏,在Angular中也有一样的效劳
$timeout 效劳

angular.module('myApp').controller('myCtrl', function($scope, $timeout) {
    $scope.myHeader = "Hello World!";
    $timeout(function () {
       $scope.myHeader = "How are you today?";
    }, 2000);
});
//要在模块中引入

$interval 效劳

angular.module('myApp').controller('myCtrl', function($scope, $timeout) {
    $scope.theTime = new Date().toLocaleTimeString();
    $interval(function () {
        $scope.theTime = new Date().toLocaleTimeString();
    }, 1000);
    //时候绑定。
});

自定义效劳

建立自定义效劳

3种建立自定义效劳的体式格局。

  • Factory
  • Service
  • Provider

之前也没有提到过,Angular这套框架最最先是由背景职员开辟的,运用了背景早就存在的分层头脑。所以项目也是运用这一设想情势。由此建立自定义效劳时用到了上述三种体式格局。

Factory

factory体式格局建立的效劳,作用就是返回一个有属性有要领的对象。

//经由过程工场情势建立自定义效劳
//一样能够注入依靠,但不能注入$scope作用域对象。
angular.module("MetronicApp").factory('myFactory', ['$resource','UrlConfig',function($resource,UrlConfig) {
    var service = {};//定义一个Object对象'
    service.name = "龙傲天";
    service._getUrl = UrlConfig.url;
    var age;//定义一个私有化的变量
    //对私有属性写getter和setter要领
    service.setAge = function(newAge){
        age = newAge;
    }
    service.getAge = function(){
        return age; 
    }
    //原始需求概况
    service.getUrl = function (id) {
        return $resource(service._getUrl).get({orderId: id});
    };
    return service;//返回这个Object对象
}]);
//建立控制器
angular.module("MetronicApp").controller('myCtrl',['$scope', 'myFactory',function($scope, myFactory) {
    $scope.name = myFactory.name;
    myFactory.setAge(20);
    $scope.age =myFactory.getAge();
    myFactory.getUrl(id).$promise.then(function (result) {
      scope.model = result.data;
    });;
}]);

service

在service运用组织函数的要领去用它,在控制器中是以new的体式格局引入,所以能够挪用 service中定义的属性

//经由过程工场情势建立自定义效劳
//依靠注入其他模块
angular.module("MetronicApp").controller("myCtrl",['$scope'',myService',function($scope,myService){  
  $scope.name=myService.name;
  myService.get(id).$promise.then(function (result) {
    $scope.model = result.data;
  });
}])

/*Service是new出来的,所以能够直接挪用内里的属性*/
angular.module("MetronicApp").service("myService",['$resource','UrlConfig',function($resource,UrlConfig){
   this.name = '龙傲天';
   this.url = UrlConfig.url;
   this.get = function (id) {
        return this.$resource(this._getUrl).get({orderId: id});
    };
}])

Provider

假如想在 service 对象启用之前,先举行模块局限的设置,那就应当挑选 provider。
当你运用Provider建立一个自定义效劳时,能够经由过程$get()函数返回内容,唯一能够写进config设置阶段的一种。假如效劳,必需要在设置阶段实行,那末必需运用provider。

运用Provider的长处就是,你能够在Provider对象通报到运用程序的其他部份之前在app.config函数中对其举行修正。

//名字必需相符范例:myProvider(你的Provider效劳名字)+Provider
angular.module("MetronicApp").config(function(myProviderProvider){
  myProviderProvider.name = "龙傲天"
})
//运用$get要领关联对应的config
angular.module("MetronicApp").provider("myProvider",['$resource','UrlConfig',function($resource,UrlConfig){
  this.$get = function(){
    return {
      name : this.name,
      age : 18,
      url : UrlConfig.url ,
      getData : function(id){
        return this.$resource(UrlConfig.url).get({orderId: id});
      }
    }
  } 
}])

angular.module("MetronicApp").controller("myCtrl",['$scope','myProvider',function($scope,myProvider){
  $scope.model = {
    name : myProvider.name,
    age : myProvider.age,
    url : myProvider.url,
  }
  myProvider.getData(id).$promise.then(function (result) {
    $scope.model.data = result.data;
  });
}])

constant和value

运用constant和value要领建立效劳,常用于返回一个常量。

angular.module("MetronicApp").constant('$age', {
 age: '18'
});
angular.module("MetronicApp").value('$name', {
  name : '龙傲天'
});
angular.module("MetronicApp").controller('MyController', function($scope, $age, $name){
  $scope.name = $name.name
  $scope.USD = $age.age
})

过滤器中运用自定义效劳

angular.module("MetronicApp").service("myService",['UrlConfig',function(UrlConfig){
   this.name = '龙傲天';
   this.url = UrlConfig.url;
   this.getUrl = function (url) {
        var arr=url.split('/');
        arr.push(this.url);
        arr.push(this.name);
        return arr.join('/')
    }
}])
app.filter('myFilter',['myService', function(myService) {
    return function(url) {
        return myService.getUrl(url);
    };
}]);

治理效劳的依靠

增加自定义效劳依靠项要领

我们在自定义效劳时,会依靠对象或效劳,有下面三种体式格局:

(1) 隐式声明

在参数中直接挪用,但这类体式格局在代码紧缩时注入的对象可能会失效

angular.module("MetronicApp").service("myService", function($resource,UrlConfigService) {
 //code
})

(2) 挪用$inject属性

function myService($resource,UrlConfigService) {
//code
}
myService.$inject = ['$resource','UrlConfigService'];
angular.module('MetronicApp').service('myService', myService);

(3) 显式声明

在建立效劳的函数中,增加一个数组,在数组中按递次声明须要注入的效劳或对象称号,这类体式格局既高效也不会丧失代码,引荐运用(在上述实例中我们是用的都是此要领)

angular.module("MetronicApp").service("myService",['$resource','UrlConfig',function($resource,UrlConfig){
   this.name = '龙傲天';
   this.url = UrlConfig.url;
   this.get = function (id) {
        return this.$resource(this._getUrl).get({orderId: id});
    };
}])

在angular的modul(模块)中注入效劳,也能够在定义modul时运用数组作为第二个参数,在此处把效劳注入进去,如许在函数体中运用不一致的效劳称号也是能够的,不过要确保注入的递次是一致的。(这个作为交叉,项目中能够运用定义的效劳称号,也能定义简化参数称号)注重此要领只针对显式声明有用。

angular.module("MetronicApp").controller("myCtrl",['$scope'',myDemandManageService',function($scope,myService){ 
   //这里的myService就是指myDemandManageService;
  $scope.name=myService.name;
  myService.get(id).$promise.then(function (result) {
    $scope.model = result.data;
  });
}])

嵌套注入效劳

在Angular中,偶然须要将一个自定义的效劳注入到另一个自定义的效劳中,构成嵌套注入的情势,平常只须要将被注入的效劳作为内置效劳,采纳显式声明的体式格局注入即可。
// 运用factory定义confirm效劳

angular.module("MetronicApp").factory('confirm', ['$window', function ($win) {
   return function (msg) {
     $win.confirm(msg);
  }
}]);
// 将confirm效劳显式的注入到fontWay效劳中
angular.module("MetronicApp").service('fontWay', ['$window', 'confirm', function ($win, con) {
  return function (t, msg) {
    return (t) ? con(msg) : $win.alert(msg);
  }
}]);
angular.module("MetronicApp").controller('MyCtrl', ['$scope', 'fontWay', function ($scope, fontWay) {
  $scope.ask = function (t, msg) {
    fontWay(t, msg);
  }
}])

效劳的其他设置

建立好的效劳平常比较复杂,假如后期须要修正,每每面对很高的风险,Angular为效劳增加了一些设置项,如装潢器(decorator),能够在不修正原代码的状况下为效劳增加其他功用。

效劳的装潢器(decorator)

装潢器(decorator)是Angular中内置效劳$provide所特有的一项设置函数,经由过程它能够阻拦效劳在实例化时建立的一些功用,并对原有功用举行优化和替换。

// 运用工场函数factory定义myService效劳

angular.module("MetronicApp").factory("myService", function () {
  return {
    name: '龙傲天',
    age: 18
  }
});
// 运用$provider的装潢器decorator为效劳myService扩大一个title属性
//症结的处所是在于decorator要领的回调函数的参数$delegate,指的是当前的数据(继续);项目中能够运用这个来做你想做的事变。
angular.module("MetronicApp").config(function ($provide) {
  $provide.decorator('myService', function ($delegate) {
    $delegate.title = 'CDS';
    return $delegate;
  })
});

angular.module("MetronicApp").controller('MyCtrl', function ($scope, myService) {
  $scope.model = myService;
});

效劳是Angular的一个难点,人人能够先明白,在项目中参照上述实例做比较。。任重而道远啊。。

    原文作者:恭弘=叶 恭弘为花而生
    原文地址: https://segmentfault.com/a/1190000012948792
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞