AngularJS開發指南14:AngularJS的服務詳解

來源:互聯網
上載者:User

標籤:

服務是一種由伺服器端帶到用戶端的特性,它由來已久。AngularJS應用中的服務是一些用依賴注入捆綁在一起的可替換的對象。服務是最常和依賴注入一起用的,它也是AngularJS中的關鍵特性。

接下來,我們詳細講解下$location服務。

$location服務,解析地址欄中的URL(基於window.location),讓你在應用代碼中能擷取到。改變地址欄中的URL會反應到$location服務中,反之亦然。

$location服務:

  • 暴露當前地址欄的URL,這樣你就能
    • 擷取並監聽URL。
    • 改變URL。
  • 當出現以下情況時同步URL
    • 改變地址欄
    • 點擊了後退按鈕(或者點擊了曆史連結)
    • 點擊了一個連結
  • 一系列方法來擷取URL對象的具體內容用(protocol, host, port, path, search, hash)

window.location和$location.service的區別:

  window.location $location.service
目的 允許對當前瀏覽器位置的讀寫 同左
API 暴露一個能被讀寫的對象 暴露jquery風格的讀寫器
是否在AngularJS應用生命週期中和應用整合 否 在應用聲明周期內的每一個階段可擷取到,並且和$watch整合
是否和HTML5 API的無縫整合 否 是(對低級瀏覽器優雅降級)
和應用的上下文是否相關 否,window.location.path返回"/docroot/actual/path" 是,$location.path()返回"/actual/path"
什麼時候該用$location

在你想對URL的改變做出響應時,或者在你想改變當前URL時。

它不能用來幹什麼

在URL改變時,不能重新整理整個頁面。一定要的話,用低級的API,$window.location.href。

$location服務的具體行為取決於它初始化時的配置。預設設定對大多數應用都是適合的,你也可以自訂配置來增加些新特性。

$location服務初始化好以後,你就可以使用jquery風格的讀寫器和它互動了,你可以擷取或者改變當前URL。

要配置$location服務,檢索$locationProvider並把參數設定成以下這樣:

    • html5Mode(模式): {boolean}
      true - 參閱HTML5模式
      false - 參閱Hashbang模式
      default: false

    • hashPrefix(首碼): {string}
      Hashbang URLs的首碼 (在Hashbang模式中或者低級瀏覽器中使用)
      default: ‘!‘

配置樣本
$locationProvider.html5Mode(true).hashPrefix(‘!‘);
讀寫器(getter and setter)

$location服務為URL唯讀部分(absUrl, protocol, host, port)提供讀方法,為可讀寫部分(url, path, search, hash)提供讀寫方法。

所有的寫方法返回同一個$location對象來支援鏈式操作。

$location服務有一個特殊的replace方法可以用來告訴$lacation服務下一次自動和瀏覽器同步,上一條瀏覽記錄應該被替換而不是建立一個新的。這在重新導向的時候很好用。不這樣的話容易使後退按鈕失效(點後退時會又觸發重新導向)。要改變URL而不添加新的記錄,你可以這樣做:

$location.path(‘/someNewPath‘);$location.replace();// or you can chain these as: $location.path(‘/someNewPath‘).replace();

注意:寫方法並不會馬上更新window.location,而是在範圍的$digest階段將多個$location操作合并成一個對windiow.location對象的commit操作。因為多個操作之後對瀏覽器來說都會只是一個,所以只要調用一次replace()方法就能實現瀏覽器記錄的替換操作。一旦瀏覽器更新了,$location服務就會將replace方法的標誌重設,以後的改變就會建立新的記錄,直到再次調用replace方法。

你可以給$location服務傳遞特殊字元,它會根據RFC 3986規則來編碼。當你調用寫方法時:

  • 所有傳遞給寫方法(如path(), search(), hash())的值都會被編碼。
  • 讀方法(path(), search(), hash()不帶參數的調用)返回解碼後的值。
  • 當你調用absUrl()時,會返回各部分經過了編碼的完整url。
  • 當你調用url()時,返回的值是path, search 和hash,形式是/path?search=a&b=c#hash。

$location服務有兩種用來控制地址欄URL格式的配置:Hashbang模式(預設)和HTML5模式(使用HTML5曆史API)。應用會使用兩種模式中相同的API,並且$location服務會使用需要的URL片段和瀏覽器API來協助改變URL或者進行曆史管理。

它們兩者的區別:

               Hashbang模式               HTML5模式配置:               預設                   { html5Mode: true }URL格式:             所有瀏覽器都支援hashbang URLs      在進階瀏覽器中使用regular URLs,低級瀏覽器使用hashbang URLs<a href=""> 連結重寫:      否                     是需要伺服器端配置:         否                    是
Hashbang模式(預設mode)

使用這個模式的話,$location會在所有瀏覽器中使用Hashbang URLs。

支援網路爬蟲

你需要添加特別的meta標記在你的文檔的頭部才能支援對你的AJAX應用的索引。

<meta name="fragment" content="!" />

這能讓網路爬蟲,請求帶有_escaped_fragment_形式的參數連結,這樣你就能識別爬蟲並且返回一個HTML的快照了。

HTML5模式

在HTML5模式中,$location服務的讀寫器和瀏覽器的URL地址通過HTML5曆史API互動,這使你能用regular URL path搜尋各組成部分,和hashbang是等效的。 

  • 在低級瀏覽器中使用了regular URL -> 重新導向成hashbang URL
  • 在現代瀏覽器中開啟了一個hashbang URL -> 重寫成regular URL
低級瀏覽器使用的降級

在支援HTML5 曆史 API的瀏覽器中,$location服務的讀寫器和瀏覽器的URL地址通過HTML5曆史API互動。 如果瀏覽器不支援HTML5 曆史API, $location服務會自動降級成使用hashbang URLs。你就不用擔心瀏覽器的支援性了。$location服務總是會用最好的選擇。

Html連結重寫

當你使用曆史API模式時,在不同的瀏覽器中你需要使用不同的連結,但是你需要做的僅僅是指定好regular URL形式的連結,如 <a href="/some?foo=bar">link</a>。

當使用者點擊這個連結時

  • 在低級瀏覽器中,URL轉換成/index.html#!/some?foo=bar
  • 在現代瀏覽器中轉換成/some?foo=bar

如果是下面的這幾種形式,連結不會被重寫。取而代之的是,瀏覽器會根據連結重新載入頁面。

  • 包含target的連結
    Example: <a href="/ext/link?a=b" target="_self">link</a>

  • 指向其他域的絕對路徑 Example: <a href="http://angularjs.org/">link</a>

  • 當base被定義時,使用‘/‘開頭指向一個不同的base路徑。 Example: <a href="/not-my-base/link">link</a>

相對連結

記住要檢查所有的相對串連、圖片、指令碼等。你必須指定你首頁面的base url(<base href="/my-base">),或者你使用絕對路徑也行,因為相對路徑會結合文檔的初始絕對路徑轉換成絕對路徑。文檔初始路徑通常和應用的根路徑不一樣。

我們強烈推薦應用使用文檔根節點開始的曆史API,因為它能處理好所有相對路徑的問題。

不同瀏覽器中的連結

因為HTML模式的重寫能力,你的使用者能在低級瀏覽器中使用regualr url,在現代瀏覽器中使用hashbang url。

  • 在進階瀏覽器中會將hashbang URLs重寫成regular URLs。
  • 在低級瀏覽器中使用了regular URL會被重新導向成hashbang URL。
注意頁面的重新載入

$location服務只能讓你改變URL;不能讓你重新載入頁面。當你需要重新載入頁面或者跳轉到另外的頁面時,請使用更低層級的API,$window.location.href。

在範圍生命週期外使用$location

$location知道應用範圍的聲明周期。當URL改變時,它會更新$location,並且調用$apply,這樣所有監聽它的程式都會收到。當你在$digest階段時改變URL。$location將改變傳遞給瀏覽器,並且通知所有的監聽者。但是如果在應用之外使用$location的話(比如,在DOM事件中或者測試中),你就要手動調用它的$apply方法來傳遞改變了。

$location.path() 和 "!" "/" 首碼

一個路徑應該總是以斜杠開始;$location.path()寫方法會在沒有首碼"/"時自動添加。

注意,hashbang模式中的"!"首碼實際上不是$location.path()的一部分,它其實是hashPrefix。

$location的雙向繫結

AngularJS的編譯器目前不支援對$location對象的雙向繫結。如果你需要對$location對象(在input元素上使用ngModel指令)進行雙向繫結,你需要指定一個帶有兩個監聽者的額外的模型屬性(比如locationPath),這兩個監聽者各負責一個方向。

<!-- html --><input type="text" ng-model="locationPath" />
// js - controller$scope.$watch(‘locationPath‘, function(path) { $location.path(path);});$scope.$watch(‘$location.path()‘, function(path) { scope.locationPath = path;});

 

 

 

 

加油!

AngularJS開發指南14:AngularJS的服務詳解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.