这篇博客,只是简单地说下 AngularJS 中的常用的系统(自带)服务。如果逻辑不清晰,就当作是一个参考手册吧,来查查用法什么的。
另外,附上一些参考网站:
AngularJS 手册:(汇智网)
AngularJS 常用服务:(AngularJS 官方文档)
$http 是对 Ajax(XHR)的封装。这里介绍 3 种用法。
- $http.get(url).success(function(data) {
- // 这里的data是一个object,是我们想要的数据部分,不包含状态码等
- // 成功的回调
- }).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"。
如果不甚了解 jsonp,可以看下这里:。
简单来说,因为同源策略的存在,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);
- });
此外,put、delete 等,可以直接看手册,这里就不多说了。而且,格式都是差不多的:
举个例子,以我测试的代码打开的 url:
在 controller 中注入 $location 服务,打印出来各个方法(代码就不掩饰了,直接贴结果):
上面我们看到,这些方法不填入参数的话,是作为 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
$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>
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()来重新定位
- }
- }
- }]);
效果(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 是应用程序一个会话(Session)中的缓存服务,以 key-value 对的方法存储一些临时数据。它跟浏览器本地缓存 localStorage 是不一样的。$cacheFactory 在用户删除当前会话(比如强制刷新页面)之后,缓存的数据就被清空了。
- var cache = $cacheFactory('firstCache');
- cache.put(key, value);
- cache.get(key); // 如果不存在这个key的话,会返回undefined
- cache.put(key, value);
- cache.remove(key); // 删除某个kv对
- cache.removeAll(); // 删除该缓存的全部kv对
- cache.destroy(); // 把当前缓存删除掉
- cache.put(key, value); // 错误!不能再访问该缓存,要重新生产一个实例出来
$timeout 和 $interval 是 AngularJS 自带的服务,跟原生 js 中的 setTimeout 和 setInterval 函数的用法基本是一样的。但是有两个不一样的地方需要注意一下:
- // 错误的写法示例(使用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);
- }]);
- // 正确的写法示例
- 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);
- }]);
所以,在 AngularJS 中,最好不要用 setTimeout 或 setInterval,而是用那两个 AngularJS 系统服务。
- // setTimeout
- var id = setTimeout(func, 2000); // 返回该timeout的id
- clearTimeout(id); // 使用clearTimeout
- // $timeout服务
- var promise = $timeout(f, 2000); // 返回一个promise对象
- $timeout.cancel(promise); // 还是要使用服务,它的cancel方法
$document 是对浏览器对象 window.document 的 jqLite 封装,主要操作 DOM(虽然一般来说不建议在 AngularJS 中操作 DOM)。其实,$document 就等同于 AngularJS 中提供的另一种服务 element,它也是用来把原生的 DOM 元素封装成 jqLite 对象,即有:
$document 等效于 angular.element(document),不过要注意两者的引用并不相等
并且,取 0 下标可以得到原生的 document 对象:
$document[0] === document,即引用相等,因为是对浏览器的 document 对象的封装
$log 服务很简单,就是更高级的 console.log 罢了,它提供 5 个方法:
是不是跟 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>
js:
- angular.module('myDemo', []).controller('LogController',
- function($scope, $log) {
- $scope.$log = $log;
- });
效果(浏览器 F12 打开控制台):
"sce" 指的是 "Strict Contextual Escaping",它是默认开启的,负责拒绝一些不安全的行为,比如加载不同源的资源等等。但是有时候,我们又需要加载一些特定的资源,我们就得使用 $sce 的一些方法,来为这些资源和 AngularJS 系统之间建立信任。
$sce 有以下常用方法:
举个例子,假如我要显示(可以理解成渲染,相当于 Android SDK 中的 webView)一段 html 文本表示的内容,我们需要遵循以下步骤:
例子:
html:
- <div ng-controller="LogController">
- <!--这里不能用ng-bind,因为是渲染一段html文本,而不是显示简单的数据-->
- <div ng-bind-html="results">
- </div>
- </div>
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);
- });
效果:
来源: http://lib.csdn.net/article/angularjs/42909