## Backbone.Router(路由)
web應用程序通常需要為應用的重要位置提供可鏈接,可收藏,可分享的 URLs。 直到最近, 貓點(hash)片段(`#page`)可以被用來提供這種鏈接, 同時隨著 History API 的到來,貓點已經可以用于處理標準 URLs (`/page`)。 **Backbone.Router** 為客戶端路由提供了許多方法,并能連接到指定的動作(actions)和事件(events)。 對于不支持 History API 的舊瀏覽器,路由提供了優雅的回調函數并可以透明的進行 URL 片段的轉換。
頁面加載期間,當應用已經創建了所有的路由,需要調用 `Backbone.history.start()`,或 `Backbone.history.start({pushState: true})` 來確保驅動初始化 URL 的路由。
**extend**`Backbone.Router.extend(properties, [classProperties])`
開始創建一個自定義的路由類。當匹配了 URL 片段便執行定義的動作,并可以通過 [routes](#Router-routes) 定義路由動作鍵值對。 請注意,你要避免在路由定義時使用前導斜杠:
```
var Workspace = Backbone.Router.extend({
routes: {
"help": "help", // #help
"search/:query": "search", // #search/kiwis
"search/:query/p:page": "search" // #search/kiwis/p7
},
help: function() {
...
},
search: function(query, page) {
...
}
});
```
**routes**`router.routes`
routes 將帶參數的 URLs 映射到路由實例的方法上(或只是直接的函數定義,如果你喜歡),這與 [View(視圖)](#View) 的 [events hash(事件鍵值對)](#View-delegateEvents) 非常類似。 路由可以包含參數, `:param`,它在斜線之間匹配 URL 組件。 路由也支持通配符, `*splat`,可以匹配多個 URL 組件。 路由的可選部分放在括號中`(/:optional)`。
舉個例子,路由 `"search/:query/p:page"` 能匹配`#search/obama/p2` , 這里傳入了 `"obama"` 和 `"2"` 到路由對應的動作中去了。
路由 `"file/*path"`可以匹配 `#file/nested/folder/file.txt`,這時傳入動作的參數為 `"nested/folder/file.txt"`。
路由 `"docs/:section(/:subsection)"`可以匹配`#docs/faq` 和 `#docs/faq/installing`,第一種情況,傳入 `"faq"` 到路由對應的動作中去, 第二種情況,傳入`"faq"` 和 `"installing"` 到路由對應的動作中去。
結尾的斜杠會被當作URL的一部分, 訪問時會被(正確地)當作一個獨立的路由。 `docs` 和 `docs/`將觸發不同的回調。 如果你不能避免產生這兩種類型的URLs時, 你可以定義一個`"docs(/)"`來匹配捕捉這兩種情況。
當訪問者點擊瀏覽器后退按鈕,或者輸入 URL ,如果匹配一個路由,此時會觸發一個基于動作名稱的 [event](#Events), 其它對象可以監聽這個路由并接收到通知。 下面的示例中,用戶訪問 `#help/uploading` 將從路由中觸發 `route:help` 事件。
```
routes: {
"help/:page": "help",
"download/*path": "download",
"folder/:name": "openFolder",
"folder/:name-:mode": "openFolder"
}
```
```
router.on("route:help", function(page) {
...
});
```
**constructor / initialize**`new Router([options])`
當創建一個新路由是,你可以直接傳入 [routes](#Router-routes) 鍵值對象作為參數。 如果定義該參數, 它們將被傳入 `initialize` 構造函數中初始化。
**route**`router.route(route, name, [callback])`
為路由對象手動創建路由,`route` 參數可以是 [routing string(路由字符串)](#Router-routes) 或 正則表達式。 每個捕捉到的被傳入的路由或正則表達式,都將作為參數傳入回調函數(callback)。 一旦路由匹配, `name` 參數會觸發 `"route:name"` 事件。如果`callback`參數省略 `router[name]`將被用來代替。 后來添加的路由可以覆蓋先前聲明的路由。
```
initialize: function(options) {
// Matches #page/10, passing "10"
this.route("page/:number", "page", function(number){ ... });
// Matches /117-a/b/c/open, passing "117-a/b/c" to this.open
this.route(/^(.*?)\/open$/, "open");
},
open: function(id) { ... }
```
**navigate**`router.navigate(fragment, [options])`
每當你達到你的應用的一個點時,你想保存為一個URL, ?可以調用**navigate**以更新的URL。 如果您也想調用路由功能, 設置**trigger**選項設置為`true`。 無需在瀏覽器的歷史記錄創建條目來更新URL, ?設置 **replace**選項設置為`true`。
```
openPage: function(pageNumber) {
this.document.pages.at(pageNumber).open();
this.navigate("page/" + pageNumber);
}
# Or ...
app.navigate("help/troubleshooting", {trigger: true});
# Or ...
app.navigate("help/troubleshooting", {trigger: true, replace: true});
```
**execute**`router.execute(callback, args)`
這種方法在路由內部被調用, ?每當路由和其相應的**callback**匹配時被執行。 覆蓋它來執行自定義解析或包裝路由, 例如, 在傳遞他們給你的路由回調之前解析查詢字符串,像這樣:
```
var Router = Backbone.Router.extend({
execute: function(callback, args) {
args.push(parseQueryString(args.pop()));
if (callback) callback.apply(this, args);
}
});
```