您的位置:首页 > 理论基础 > 计算机网络

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

2018-01-05 18:27 591 查看
这篇博客,只是简单地说下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) {
// 出错的回调
});
1
2
3
4
5
6
7


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

var url = "...";
var postData = {
id: "123",
token: "x1234q3412fwdfw3r23"
};
$http.post(url, postData)
.success(function (data) {
// 成功的回调
}).error(function (err) {
// 出错的回调
});
1
2
3
4
5
6
7
8
9
10
11

题外话:这里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);
});
1
2
3
4
5
6
7
89
10

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




二、$location(配合$anchorScroll)

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

方法: 




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

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

在controller中注入$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[/code]1 2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

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()来重新定位
}
}
}]);
1
2
3
4
5
6
7
8
9
10
11
12

效果(gif): 



   这里为什么要用到$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');
1


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

cache.put(key, value);
1


(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); // 错误!不能再访问该缓存,要重新生产一个实例出来
1
2
3


四、$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文本表示的内容,我们需要遵循以下步骤:
在html模板中用“ng-bind-html”属性来绑定一个model(变量);
在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

效果: 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: