http://blog.csdn.net/vitalemon__/article/details/52163866    链接地址

AngularJS常用服务($http、$location、$sce等)

原创 2016年08月09日 17:29:25

这篇博客,只是简单地说下AngularJS中的常用的系统(自带)服务。如果逻辑不清晰,就当作是一个参考手册吧,来查查用法什么的。 
另外,附上一些参考网站: 
AngularJS手册:http://man.hubwiz.com/manual/AngularJS(汇智网) 
AngularJS常用服务:https://docs.angularjs.org/api/ng/service(AngularJS官方文档)

一、$http


$http是对Ajax(XHR)的封装。这里介绍3种用法。

1、GET请求的用法:

$http.get(url)
    .success(function (data) { 
        // 这里的data是一个object,是我们想要的数据部分,不包含状态码等
        // 成功的回调
    }).error(function (err) {
    // 出错的回调
});
  • $http.get(url) .success(function (data) { // 这里的data是一个object,是我们想要的数据部分,不包含状态码等 // 成功的回调 }).error(function (err) { // 出错的回调 });

2、POST请求的用法也差不多,只是多了参数:

var url = "...";
var postData = {
    id: "123",
    token: "x1234q3412fwdfw3r23"
};
$http.post(url, postData)
    .success(function (data) { 
        // 成功的回调
    }).error(function (err) {
    // 出错的回调
});
  • var url = "..."; var postData = { id: "123", token: "x1234q3412fwdfw3r23" }; $http.post(url, postData) .success(function (data) { // 成功的回调 }).error(function (err) { // 出错的回调 });

题外话:这里post请求的参数的数据类型,默认是“application/json”,而jQuery的post默认用的“application/x-www-form-urlencoded”。

3、jsonp:

如果不甚了解jsonp,可以看下这里:http://kb.cnblogs.com/page/139725/。 
简单来说,因为同源策略的存在,Ajax脚本不能跨域访问资源,所以我们只能把回调函数作为参数之一传给服务器,让服务器端返回数据的时候指定调用我们的回调函数。所以,我们只需要把回调函数写好就可以了,在这里,我们写在success中:

// 在jsonp中,url的最后必须严格带上“&callback=JSON_CALLBACK”,而且名字不能改
var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1&callback=JSON_CALLBACK";

$http.jsonp(url)
       .success(function (data) { // 在这里定义JSON_CALLBACK。其实与GET差不多
            console.log('jsonp:', data)
        })
        .error(function (err) {
            console.log('error', err);
        });
  • // 在jsonp中,url的最后必须严格带上“&callback=JSON_CALLBACK”,而且名字不能改 var url = "http://www.phonegap100.com/appapi.php?a=getPortalList&catid=20&page=1&callback=JSON_CALLBACK"; $http.jsonp(url) .success(function (data) { // 在这里定义JSON_CALLBACK。其实与GET差不多 console.log('jsonp:', data) }) .error(function (err) { console.log('error', err); });

此外,put、delete等,可以直接看手册,这里就不多说了。而且,格式都是差不多的: 
AngularJS手册

二、$location(配合$anchorScroll)


  • 简介:使用$location可以得到当前页面url的参数。用户对于Url做出的改变,会通知到$location中,而$location对Url的一些操纵也会反映到地址栏上面。

  • 方法: 
    $location服务的方法

1、没有参数时,作为getter,获取url信息:

举个例子,以我测试的代码打开的url: 
http://localhost:63342/test/templates/demo01.html#/hello?name=jk&age=10#helloworld

在controller中注入$location服务,打印出来各个方法(代码就不掩饰了,直接贴结果): 
$location打印信息

2、有参数的时候,作为setter,(部分地)改变当前url:

上面我们看到,这些方法不填入参数的话,是作为getter使用。而其中有4个方法,当填入参数的时候可以作为url的setter来使用,并且返回该$location服务(以便链式调用),这4个方法可以从上面截图中看到: 
- $location.url(urlValue) 
- $location.path(pathValue) 
- $location.hash(hashValue) 
- $location.search(paramObj)

例子:

// 假定原来的完整url为:
// http://localhost:63342/test/templates/demo01.html#/tabs/chat?name=JK&age=10#noHash


var url = $location.url("url2").absUrl();
// 到这里变成:
// http://localhost:63342/test/templates/demo01.html#/url2


url = $location.path("path2")
    .search({
        name: "CL",
        age: 12
    })
    .hash('hash2')
    .absUrl();
// 到这里变成:
// http://localhost:63342/test/templates/demo01.html#/path2?name=CL&age=12#hash2
  • // 假定原来的完整url为: // http://localhost:63342/test/templates/demo01.html#/tabs/chat?name=JK&age=10#noHash var url = $location.url("url2").absUrl(); // 到这里变成: // http://localhost:63342/test/templates/demo01.html#/url2 url = $location.path("path2") .search({ name: "CL", age: 12 }) .hash('hash2') .absUrl(); // 到这里变成: // http://localhost:63342/test/templates/demo01.html#/path2?name=CL&age=12#hash2

3、对$location.hash([id])的特别说明:

$location的hash方法填入一个DOM元素的id值,可以快速定位到该DOM元素。比如以下程序。 
程序说明:设定5个div,通过点击5个列表项可以快速定位到这5个div: 
demo01.html:

<div id="parent" ng-controller="firstController">

    <!--以下为5个列表项,可以点击,以改变hash值,定位到某个div块-->
    <ol>
        <li ng-repeat="id in [1,2,3,4,5]" ng-click="goTo('div'+id);">Go to div{{id}}</li>
    </ol>

    <!--以下为5个div块-->
    <div id="div1">This is div1.</div>
    <div id="div2">This is div2.</div>
    <div id="div3">This is div3.</div>
    <div id="div4">This is div4.</div>
    <div id="div5">This is div5.</div>
</div>
  • <div id="parent" ng-controller="firstController"> <!--以下为5个列表项,可以点击,以改变hash值,定位到某个div块--> <ol> <li ng-repeat="id in [1,2,3,4,5]" ng-click="goTo('div'+id);">Go to div{{id}}</li> </ol> <!--以下为5个div块--> <div id="div1">This is div1.</div> <div id="div2">This is div2.</div> <div id="div3">This is div3.</div> <div id="div4">This is div4.</div> <div id="div5">This is div5.</div> </div>

css文件就不贴出来了。以下是js文件 
demo01_app.js:

angular.module('myDemo', [])

    .controller('firstController', ['$scope', '$location', '$anchorScroll', function ($scope, $location, $anchorScroll) {

        $scope.goTo = function (id) {
            if (id !== $location.hash()) { // 如果hash值改变了
                $location.hash(id);        // 就用hash方法,定位到那个div
            } else {             // 如果hash值没有改变
                $anchorScroll(); // 就显式调用$anchorScroll()来重新定位
            }
        }
    }]);
  • angular.module('myDemo', []) .controller('firstController', ['$scope', '$location', '$anchorScroll', function ($scope, $location, $anchorScroll) { $scope.goTo = function (id) { if (id !== $location.hash()) { // 如果hash值改变了 $location.hash(id); // 就用hash方法,定位到那个div } else { // 如果hash值没有改变 $anchorScroll(); // 就显式调用$anchorScroll()来重新定位 } } }]);

效果(gif): 
hash

   这里为什么要用到$anchorScroll这个服务呢?通过测试我发现,如果每次都只调用hash方法来定位元素的话,会出现这么一种情况,使得$location的hash()方法是无效的:(为了可以随时跳转,我把5个可点击的列表项的position属性设成“fixed”,即固定在屏幕的某个位置)当我点击“Go to div1”的时候跳到了div1,此时Url中的hash值是“##div1”,到这里没问题。但这时候,如果我滚动屏幕到最底端,大概到达div5的位置的时候再点击“Go to div1”,是不能再跳转到div1块的,因为hash值没有改变,$location.hash()这个方法是“无效”的。所以,这种情况就要请$anchorScroll服务出来了,它负责这种特殊情况下的跳转,而它在这里也只简单地调用了一下方法而已。

三、$cacheFactory


1、介绍:

$cacheFactory是应用程序一个会话(Session)中的缓存服务,以key-value对的方法存储一些临时数据。它跟浏览器本地缓存localStorage是不一样的。$cacheFactory在用户删除当前会话(比如强制刷新页面)之后,缓存的数据就被清空了。

2、用法:

(1)首先,要得到一个缓存实例,用id来区分,比如我想取id为’firstCache’的缓存:

var cache = $cacheFactory('firstCache');

 

(2)添加kv对,put方法:

cache.put(key, value);

(3)获取,get方法:

cache.get(key); // 如果不存在这个key的话,会返回undefined
  • 1

(4)添加kv对,put方法:

cache.put(key, value);
  • 1

(5)删除,remove和removeAll:

cache.remove(key); // 删除某个kv对
cache.removeAll(); // 删除该缓存的全部kv对
  • 1
  • 2

(6)删除该缓存实例,destroy:

cache.destroy(); // 把当前缓存删除掉

cache.put(key, value); // 错误!不能再访问该缓存,要重新生产一个实例出来

四、$timeout、$interval


1、介绍:

$timeout和$interval是AngularJS自带的服务,跟原生js中的setTimeout和setInterval函数的用法基本是一样的。但是有两个不一样的地方需要注意一下:

  • 区别一: 
    原生js中的两个函数,如果在AngularJS中使用并且在回调函数中需要使用$scope服务的话,我们需要用$angular.$apply把回调函数包起来,因为这里setTimeout函数被AngularJS当作是外部函数了。就像这样:
// 错误的写法示例(使用setTimeout却没有用$apply):
angular.module('myDemo', [])

    .controller('firstController', ['$scope', function ($scope) {

        setTimeout(function () {
            console.log('before');  // 正常输出before
            $scope.name = "My name have been changed."; // 这一句不被执行
            console.log('after');   // 正常输出after
        }, 2000);
    }]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
// 正确的写法示例
angular.module('myDemo', [])

    .controller('firstController', ['$scope', function ($scope) {

        setTimeout(function () {
            console.log('before');  // 正常输出before
            $scope.$apply(function () {
                $scope.name = "My name have been changed.";  // 正确显示
            });
            console.log('after');   // 正常输出after
        }, 2000);
    }]);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

所以,在AngularJS中,最好不要用setTimeout或setInterval,而是用那两个AngularJS系统服务。

  • 区别二:取消的方式不大一样,比如timeout:
// setTimeout
var id = setTimeout(func, 2000); // 返回该timeout的id
clearTimeout(id);                // 使用clearTimeout
  • 1
  • 2
  • 3
// $timeout服务
var promise = $timeout(f, 2000); // 返回一个promise对象
$timeout.cancel(promise);        // 还是要使用服务,它的cancel方法
  • 1
  • 2
  • 3

2、用法:(上面有啦~)

五、$document


1、介绍、用法:

$document是对浏览器对象window.document的jqLite封装,主要操作DOM(虽然一般来说不建议在AngularJS中操作DOM)。其实,$document就等同于AngularJS中提供的另一种服务element,它也是用来把原生的DOM元素封装成jqLite对象,即有:

$document 等效于 angular.element(document),不过要注意两者的引用并不相等

并且,取0下标可以得到原生的document对象:

$document[0] === document,即引用相等,因为是对浏览器的document对象的封装

六、$log


$log服务很简单,就是更高级的console.log罢了,它提供5个方法:

  • log
  • warn
  • info
  • error
  • debug

是不是跟Android原生中的Log差不多呢^_^? 
官方实例: 
html:

<div ng-controller="LogController">
    <p>Reload this page with open console, enter text and hit the log button...</p>
    <label>Message:
        <input type="text" ng-model="message"/>
    </label>
    <button ng-click="$log.log(message)">log</button>
    <button ng-click="$log.warn(message)">warn</button>
    <button ng-click="$log.info(message)">info</button>
    <button ng-click="$log.error(message)">error</button>
    <button ng-click="$log.debug(message)">debug</button>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

js:

angular.module('myDemo', [])
    .controller('LogController', function ($scope, $log) {
        $scope.$log = $log;
    });
  • 1
  • 2
  • 3
  • 4

效果(浏览器F12打开控制台): 
这里写图片描述

七、$sce


1、介绍

“sce”指的是“Strict Contextual Escaping”,它是默认开启的,负责拒绝一些不安全的行为,比如加载不同源的资源等等。但是有时候,我们又需要加载一些特定的资源,我们就得使用$sce的一些方法,来为这些资源和AngularJS系统之间建立信任。

2、用法

$sce有以下常用方法:

  • $sce.trustAsHtml(…):将一段html文本视为安全
  • $sce.trustAsUrl(…)
  • $sce.trustAsResourceUrl(…)
  • $sce.trustAsJs(…)

举个例子,假如我要显示(可以理解成渲染,相当于Android SDK中的WebView)一段html文本表示的内容,我们需要遵循以下步骤:

  1. 在html模板中用“ng-bind-html”属性来绑定一个model(变量);
  2. 在js中注入$sce服务,并且使用方法$sce.trustAsHtml(…),把信任后的值赋给该model。

例子: 
html:

<div ng-controller="LogController">

    <!--这里不能用ng-bind,因为是渲染一段html文本,而不是显示简单的数据-->
    <div ng-bind-html="results"></div>
</div>
  • 1
  • 2
  • 3
  • 4
  • 5

controller.js:

angular.module('myDemo', [])
    .controller('LogController', function ($scope, $http, $sce) {

        // 随便定义一段html文本
        var txt = "<h1>Hello world!</h1>";

        // 这里不能直接$scope.results = txt,否则会报错显示“不安全”
        $scope.results = $sce.trustAsHtml(txt);
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

效果: 
sce效果图

posted on 2018-02-26 16:34  niunf  阅读(550)  评论(0编辑  收藏  举报