本篇介紹angular中的$location服務的基本用法,下一篇介紹它的複雜的用法.
$location服務的主要作用是用於獲取當前url以及改變當前的url,並且存入歷史記錄.
一. 獲取url的相關方法:
以 'http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash' 這個路徑為例:
1. 獲取當前完整的url路徑:
$location.absUrl():
// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
*2. 獲取當前url路徑(當前url#後面的內容,包括引數和雜湊值):
$location.url();
// /foo?name=bunny#myhash
*3. 獲取當前url的子路徑(也就是當前url#後面的內容,不包括引數):
$location.path()
// /foo
4. 獲取當前url的協議(比如http,https)
$location.protocol()
// http
5. 獲取當前url的主機名
$location.host()
// localhost
6. 獲取當前url的埠
$location.port()
// 80 (這裡就是wamp的預設埠號)
*7. 獲取當前url的雜湊值
$location.hash()
// myhash
*8. 獲取當前url的引數的序列化json物件
$location.search()
// {"name":"bunny"}
二. 修改url的相關方法:
在上面講到的所有獲取url的8個方法,其中*開頭的四個方法,可以傳入引數進行修改url,在這種情況下,函式的返回值都是$location本身:
1. 修改url的子路徑(也就是當前url#後面的內容,不包括引數):
引數格式:字串
$location.url('/foo2?name=bunny2&age=12#myhash2');
// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2
2. 修改url的子路徑部分(也就是當前url#後面的內容,不包括引數):
引數格式:字串
$location.path('/foo2/foo3');
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=bunny2&age=12#myhash2
3. 修改url的雜湊值部分
引數格式:字串
$location.hash('myhash3');
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=bunny2&age=12#myhash3
4. 修改url的引數部分
(1).傳入兩個引數,第一個引數的格式為字串:
①第二個引數的格式也是字串
第一個參數列示url引數的屬性名,第二個引數是該屬性名的屬性值,如果是已有屬性名,則修改,如果不是已有屬性,則新增
$location.search('name','code_bunny')
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2&age=12#myhash3
②第二個引數的格式為陣列,陣列中的各個值也是字串或者布林值
第一個參數列示url引數的屬性名,第二個引數是該屬性名的值,有多少個值,url中就會依次重複出現多少個.如下:
$location.search('love',['zxg','mitu'])
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2&age=12&love=zxg&love=mitu#myhash3
(2).傳入兩個引數,第一個引數為字串,第二個引數為null:
第一個值表示url引數的屬性名,如果是已有屬性名,則刪除該屬性,如果不是已有屬性,那就等於沒改過
$location.search('age',null)
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny2#myhash3
(3).傳入一個引數,格式為json物件:
直接用這個json物件裡的鍵值對替換整個url的引數部分
①普通的鍵值對:
$location.search({name:'papamibunny',age:16,love:'zxg'})
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=papamibunny&age=16&love=zxg#myhash3
②屬性值為一個陣列:(和(1)②一樣,重複這個屬性)
$location.search({name:['code_bunny','white_bunny','hua_bunny'],age:16,love:'zxg'})
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?name=code_bunny&name=white_bunny&name=hua_bunny&age=16&love=zxg#myhash3
(4).傳入一個引數,格式為字串:
直接用這個字串替換整個url的引數部分(沒有鍵值對,引數部分就是一個屬性名,但轉換成json物件的話,這個屬性的值就是true,但是在url裡沒有體現)
$location.search('bunnybaobao')
// http://localhost/$location/21.1%20$location.html#/foo2/foo3/?bunnybaobao#myhash3
// {"bunnybaobao":true}
三. 不存入歷史記錄:
在使用 '二' 裡面的所有修改url的方法的時候,每修改一次,url都會被存入歷史記錄,可以使用後退按鈕回到修改前的url,如果不想要這種效果,而僅僅是替換當前的記錄,可以使用:
$location.replace()
舉個栗子:
// 原url:
// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
$location.url('/foo2?name=bunny2&age=12#myhash2');
// 修改一次後:
// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2
// 按下後退回到原url:
// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
// 再按下前進回到修改後url:
// http://localhost/$location/21.1%20$location.html#/foo2?name=bunny2&age=12#myhash2
$location.path('/foo2/foo3').replace();
// 修改第二次後呼叫replace():
// http://localhost/$location/21.1%20$location.html#/foo2/foo3?name=bunny2&age=12#myhash2
// 按下後退,不會回到第二次修改前的url,而是回到第一次修改前的url:
// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
四.$locationChangeStart和$locationChangeStart事件
這兩個事件分別發生在當url開始發生改變,以及url改變完成.他們都被繫結在$rootScope裡面:
$rootScope.$on('$locationChangeStart',function(){ console.log('開始改變$location') }); $rootScope.$on('$locationChangeSuccess',function(){ console.log('結束改變$location') });
這個和$route裡的$routeChangeStart和$routeChangeSuccess很類似,但是要注意的是,雖然都是改變url發生的事件,但要觸發$locationChangeStart和$locationChangeSuccess事件,就必須是$location服務導致的url變化,通過$route定義導致的url變化,不會觸發$locationChangeStart和$locationChangeSuccess事件,同樣,這裡是通過$location服務導致的url變化,所以即使定義了$routeChangeStart和$routeChangeSuccess事件,它也是不會被觸發的.
把上面講到的這些一起舉個栗子:
把 '一' 裡面的8個可以取到的url部分都賦值給$scope裡的值,同時,把對應的修改方法繫結在對應的按鈕上,以便在檢視上檢視變化過程.
需要注意的是,這裡有個$scope.refresh方法,因為這裡$scope下的這些值是不會實時更新的.舉慄,$location.url()是個方法,獲取當前的url,而不是一個值,所以,當url發生改變以後,不再次呼叫$location.url(),url值是不可能被實時更新的.所以refresh方法就是在每次url改變完成後,重新獲取url對應的部分並更新檢視.
html:
<!DOCTYPE html> <html ng-app="locationApp"> <head> <title>21.1 $location</title> <meta charset="utf-8"> <script src="angular.min.js"></script> <script src="script.js"></script> </head> <body ng-controller="locationCtrl"> <p>完整url路徑: <span>{{absurl}}</span></p> <p>url路徑(當前url#後面的內容,包括引數和雜湊值): <span>{{url}}</span> <button ng-click="changeUrl()">改變</button> </p> <p>相對路徑(也就是當前url#後面的內容,不包括引數): <span>{{path}}</span> <button ng-click="changePath()">改變</button> </p> <p>協議(比如http,https): <span>{{protocol}}</span></p> <p>主機名: <span>{{host}}</span></p> <p>埠號: <span>{{port}}</span></p> <p>雜湊值: <span>{{hash}}</span> <button ng-click="changeHash()">改變</button> </p> <p>search值序列化json: <span>{{search}}</span> <button ng-click="changeSearch_1()">改變1</button> <button ng-click="changeSearch_2()">改變2</button> <button ng-click="changeSearch_3()">改變3</button> <button ng-click="changeSearch_4()">改變4</button> <button ng-click="changeSearch_5()">改變5</button> <button ng-click="changeSearch_6()">改變6</button> </p> </body> </html>
js:
/*21.1 $location*/ var locationApp = angular.module('locationApp',[]); locationApp.controller('locationCtrl',function($scope,$location,$timeout,$rootScope){ $scope.absurl = $location.absUrl(); $scope.url = $location.url(); $scope.path = $location.path(); $scope.protocol = $location.protocol(); $scope.host = $location.host(); $scope.port = $location.port(); $scope.hash = $location.hash(); $scope.search = $location.search(); $scope.refresh = function(){ $scope.absurl = $location.absUrl(); $scope.url = $location.url(); $scope.path = $location.path(); $scope.hash = $location.hash(); $scope.search = $location.search(); }; //重寫url部分,相應的absurl,url,path,hash,search都會改變 $scope.changeUrl = function(){ $location.url('/foo2?name=bunny2&age=12#myhash2'); }; //重寫path部分,相應的absurl,url,path都會改變 $scope.changePath = function(){ $location.path('/foo2/foo3'); }; //重寫hash部分,相應的absurl,url,hash都會改變 $scope.changeHash = function(){ $location.hash('myhash3'); }; //修改search部分(方法1),相應的absurl,url,search,hash都會改變 //指定兩個引數,第一個引數是屬性名,第二個引數是屬性值. //如果屬性名是已有屬性,則修改,如果屬性名不是已有的,則新增. //屬性值也可以是一個陣列,參考方法6 $scope.changeSearch_1 = function(){ $location.search('name','code_bunny'); }; //修改search部分(方法2),相應的absurl,url,search,hash都會改變 //指定兩個引數,第二個引數是null:刪除第一個引數所指定的屬性名.不再有這個屬性 //若第一個引數不是已有的,則不發生任何改變 $scope.changeSearch_2 = function(){ $location.search('age',null); }; //修改search部分(方法3),相應的absurl,url,search,hash都會改變 //指定一個引數,json物件,直接重寫整個search部分.不管是不是已有屬性,全部重寫. //這裡屬性的值可以是一個陣列,參考方法5 $scope.changeSearch_3 = function(){ $location.search({name:'papamibunny',age:16,love:'zxg'}); }; //修改search部分(方法4),相應的absurl,url,search,hash都會改變 //指定一個引數,字串,整個search部分就變為這個字串.注意是沒有屬性值的. $scope.changeSearch_4 = function(){ $location.search('bunnybaobao'); }; //修改search部分(方法5),相應的absurl,url,search,hash都會改變 //其餘和方法3一樣.全部重寫search: //指定一個引數,json格式,屬性值是一個陣列,那麼最後的search會變成name=code_bunny&name=white_bunny&name=hua_bunny $scope.changeSearch_5 = function(){ $location.search({name:['code_bunny','white_bunny','hua_bunny']}); }; //修改search部分(方法6),相應的absurl,url,search,hash都會改變 //其餘和方法1一樣,修改指定的屬性名(或新增) //第二個引數是一個陣列,最後search中的love部分會變成love=zxg&love=mitu //它和方法5的區別,就像方法1和方法3的區別,一個是修改或新增某個屬性值,一個是重置整個search $scope.changeSearch_6 = function(){ $location.search('love',['zxg','mitu']).replace(); }; //使用$location.replace(),則這一次的修改路徑不會被記錄到歷史記錄中,點選後退,不會後退到改變前的路徑,而是後退到改變前的路徑的改變前的路徑 $rootScope.$on('$locationChangeStart',function(){ console.log('開始改變$location') }); $rootScope.$on('$locationChangeSuccess',function(){
$scope.refresh(); console.log('結束改變$location') }); //這裡就算繫結了$routeChangeStart和$routeChangeSuccess,也不會被觸發,因為這裡沒有$route相關的服務. }); //注意這裡$scope下的這些值是不會實時更新的.舉慄url,$location.url()是個方法,獲取當前的url,而不是一個值, //所以,當url發生改變以後,不再次呼叫$location.url(),url值是不可能被實時更新的.
整個過程如下:
1.初始狀態,輸入如下url:
http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash
圖1.1
依次點選'改變'按鈕後:
圖1.2
----------------------------------------------------------------------------------------------------------------------------
圖1.3
----------------------------------------------------------------------------------------------------------------------------
圖1.4
----------------------------------------------------------------------------------------------------------------------------
圖1.5
----------------------------------------------------------------------------------------------------------------------------
圖1.6
----------------------------------------------------------------------------------------------------------------------------
圖1.7
----------------------------------------------------------------------------------------------------------------------------
圖1.8
----------------------------------------------------------------------------------------------------------------------------
圖1.9
----------------------------------------------------------------------------------------------------------------------------
圖1.10
此時點選後退,不會回到圖1.9,而是回到圖1.8
更多進階用法請檢視:angular學習筆記(三十一)-$location(2)