[AngularJS] $location 服務簡介
參考部落格: https://www.cnblogs.com/gaoruixin/p/6070502.html
簡介
$location服務解析在瀏覽器位址列中的URL(基於window.location)並且讓URL在你的應用中可用。改變在位址列中的URL會作用到$location服務,同樣的,改變$location服務也會改變瀏覽器的位址列。(可以使用$location進行重定向等操作)
$location服務:
暴露瀏覽器位址列中的URL,讓你可以:
- 監察URL。
- 改變URL。
與瀏覽器同步URL,當:
- 改變位址列。
- 單擊『前進』『後退』或一個歷史記錄中的連結。
- 開啟一個連結。
- 將URL物件表示為一個方法集。 (protocol, host, port, path, search, hash)
服務依賴:
- $browser
- $sniffer
- $rootElement
內建方法:
- absUrl( ):只讀;根據在RFC 3986中指定的規則,返回url,帶有所有的片段。
- hash( ):讀、寫;當帶有引數時,返回雜湊碎片;當在帶有引數的情況下,改變雜湊碎片時,返回$location。
- host( ):只讀;返回url中的主機路徑。
- path( ):讀、寫;當沒有任何引數時,返回當前url的路徑;當帶有引數時,改變路徑,並返回$location。(返回的路徑永遠會帶有/)
- port( ):只讀;返回當前路徑的埠號。
- protocol( ):只讀;返回當前url的協議。
- replace( ):如果被呼叫,就會用改變後的URL直接替換瀏覽器中的歷史記錄,而不是在歷史記錄中新建一條資訊,這樣可以阻止『後退』。
- search( ):讀、寫;當不帶引數呼叫的時候,以物件形式返回當前url的搜尋部分。
- url( ):讀、寫;當不帶引數時,返回url;當帶有引數時,返回$location。
內建事件:
- $locationChangeStart:在URL改變前發生。這種改變可以通過呼叫事件的preventDefault方法為阻止。檢視ng.$rootScope.Scope#$on
- $locationChangeSuccess:當URL改變後發生。
使用
何時使用$location
任何你想要改變當前URL的時候,都可以使用$location。
$location不會做
當瀏覽器的URL改變時,不會重新載入整個頁面。如果想要重新載入整個頁面,需要使用$window.location.href。
-----------------------------------------------------------------
一. 獲取url的相關方法:
以 'http://localhost:8080/text#/foo?name=bunny#myhash' 這個路徑為例:
1. 獲取當前完整的url路徑:
$location.absUrl():
// http://localhost:8080/text#/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:8080/text#/foo2?name=bunny2&age=12#myhash2
2. 修改url的子路徑部分(也就是當前url#後面的內容,不包括引數):
引數格式:字串
$location.path('/foo2/foo3');
// http://localhost:8080/text#/foo2/foo3/?name=bunny2&age=12#myhash2
3. 修改url的雜湊值部分
引數格式:字串
$location.hash('myhash3');
// http://localhost:8080/text#/foo2/foo3/?name=bunny2&age=12#myhash3
4. 修改url的引數部分
(1).傳入兩個引數,第一個引數的格式為字串:
①第二個引數的格式也是字串
第一個引數表示url引數的屬性名,第二個引數是該屬性名的屬性值,如果是已有屬性名,則修改,如果不是已有屬性,則新增
$location.search('name','code_bunny')
// http://localhost:8080/text#/foo2/foo3/?name=code_bunny2&age=12#myhash3
②第二個引數的格式為陣列,陣列中的各個值也是字串或者布林值
第一個引數表示url引數的屬性名,第二個引數是該屬性名的值,有多少個值,url中就會依次重複出現多少個.如下:
$location.search('love',['zxg','mitu'])
// http://localhost:8080/text#/foo2/foo3/?name=code_bunny2&age=12&love=zxg&love=mitu#myhash3
(2).傳入兩個引數,第一個引數為字串,第二個引數為null:
第一個值表示url引數的屬性名,如果是已有屬性名,則刪除該屬性,如果不是已有屬性,那就等於沒改過
$location.search('age',null)
// http://localhost:8080/text#/foo2/foo3/?name=code_bunny2#myhash3
(3).傳入一個引數,格式為json物件:
直接用這個json物件裡的鍵值對替換整個url的引數部分
①普通的鍵值對:
$location.search({name:'papamibunny',age:16,love:'zxg'})
// http://localhost:8080/text#/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:8080/text#/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:8080/text#/foo2/foo3/?bunnybaobao#myhash3
// {"bunnybaobao":true}
三. 不存入歷史記錄:
在使用 '二' 裡面的所有修改url的方法的時候,每修改一次,url都會被存入歷史記錄,可以使用後退按鈕回到修改前的url,如果不想要這種效果,而僅僅是替換當前的記錄,可以使用:
$location.replace()
舉個栗子:
// 原url:
// http://localhost:8080/text#/foo?name=bunny#myhash
$location.url('/foo2?name=bunny2&age=12#myhash2');
// 修改一次後:
// http://localhost:8080/text#/foo2?name=bunny2&age=12#myhash2
// 按下後退回到原url:
// http://localhost:8080/text#/foo?name=bunny#myhash
// 再按下前進回到修改後url:
// http://localhost:8080/text#/foo2?name=bunny2&age=12#myhash2
$location.path('/foo2/foo3').replace();
// 修改第二次後呼叫replace():
// http://localhost:8080/text#/foo2/foo3?name=bunny2&age=12#myhash2
// 按下後退,不會回到第二次修改前的url,而是回到第一次修改前的url:
// http://localhost:8080/text#/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事件,它也是不會被觸發的.