$location

本篇介紹angular中的$location服務的基本用法html

$location服務的主要做用是用於獲取當前url以及改變當前的url,而且存入歷史記錄.json

 

一. 獲取url的相關方法:數組

以 'http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash' 這個路徑爲例:app

1. 獲取當前完整的url路徑:函數

$location.absUrl():
// http://localhost/$location/21.1%20$location.html#/foo?name=bunny#myhash

*2. 獲取當前url路徑(當前url#後面的內容,包括參數和哈希值):url

$location.url();
// /foo?name=bunny#myhash

*3. 獲取當前url的子路徑(也就是當前url#後面的內容,不包括參數):spa

$location.path()
// /foo

4. 獲取當前url的協議(好比http,https)code

$location.protocol()
// http

5. 獲取當前url的主機名htm

$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

相關文章
相關標籤/搜索