英文原版:https://guides.emberjs.com/v2.13.0/routing/defining-your-routes/
當你開始運行你的app時,router會將當前的URL與你定義路由相匹配。這些路由呢,則會負責顯示模板,讀取數據並且更新app狀態。
定義路由,命令:
ember generate route route-name
這個命令創建了個一個路由源文件:app/routes/route-name.js,一個模板文件:app/templates/route-name.hbs和一個單元測試文件:tests/unit/routes/route-name-test.js。並且會在app/router.js中添加一條路由信息。
基本路由
Ember應用的app/router.js中的map()方法會被調用,用來生成路由映射。當調用map()時,你需要給它傳一個函數,並且在函數內需要通過this.route()來定義路由。
app/router.js
Router.map(function() {
this.route('about', { path: '/about' });
this.route('favorites', { path: '/favs' });
});
好了,現在如果用戶訪問 /about 路由,Ember將會渲染about模板;若訪問/favs,則會渲染 favorites 模板。
當然如果路由名稱與名稱對象的值一樣,你也可以不設置名稱對象。下面的這個種方式與上面的例子是等價的:
app/router.js
Router.map(function() {
this.route('about');
this.route('favorites', { path: '/favs' });
});
在模板中,你可以使用{{link-to}}助手來在這這些路由之間進行導航。助手中的路由參數值,只需要跟你在router中定義的router()方法的第一各參數一致即可:
{{#link-to "index"}}<img class="logo">{{/link-to}}
<nav>
{{#link-to "about"}}About{{/link-to}}
{{#link-to "favorites"}}Favorites{{/link-to}}
</nav>
當然,你可以在{{link-to}}助手中添加一個active類,用來標示當前正在訪問的路由。
多詞名稱路由,需要你用減號來作爲每個單詞的分隔符:
app/router.js
Router.map(function() {
this.route('blog-post', { path: '/blog-post' });
});
上面定義的這個路由,默認會使用blog-post.js作爲它的處理程序,blog-post.hbs作爲模板,並且在{{link-to}}助手中通過blog-post來引用。
你可以可以使用下面這種方式來命名多詞路由:
app/router.js
Router.map(function() {
this.route('blog_post', { path: '/blog-post' });
});
這種方式仍然會以blog-post.js作爲它的處理程序、blog-post.hbs作爲模板。但是,在{{link-to}}助手中需要使用blog_post來引用。
嵌套路由
你嚐嚐也會需要使模板可以顯示它下層的其他模板。比如,在一個博客應用中,相對於在 一堆的博客列表中有個創建博客的區域,或許你更傾向於在列表頁的下一頁專門弄個創建博客的頁面。
這個時候,嵌套路由就用上了。
定義嵌套路由只需要在this.route中添加一個回調函數:
app/router.js
Router.map(function() {
this.route('posts', function() {
this.route('new');
});
});
這裏假設你已經生成了post路由,爲了生成它的嵌套路由,你可以運行下面的命令:
ember generate route posts/new
然後,在post路由中放一個 {{outlet}},用來在上層路由中顯示嵌套路由:
templates/posts.hbs
<h1>Posts</h1>
<!-- Display posts and other content -->
{{outlet}}
router會創建一個/posts映射和一個/posts/new映射。當用戶訪問/posts時,他們只會看見posts.hbs模板中的內容(注意了,回憶下之前說過的index路由)。只有當用戶訪問posts/new時,posts/new.hbs模板纔會被渲染並出現在{{outlet}}所在位置,緊接着纔會在頁面上出現。
嵌套路由的名字中包含它的祖先路由的名字。如果你想跳轉到其他路由(通過transitionTo或{{#link-to}}實現挑破轉),請確保使用完整的路由名稱,例如: 使用posts.new 而不是new。
application路由
當你的應用第一次啓動的時候,那麼將會首先進入application路由。如果其他路由一樣,所讀取的模板也是application。你可以將你的網站的header,footer或者其他始終顯示在頁面的內容放在application.hbs中。其他路由的模板將會最終將會被渲染到application.hbs模板的{{outlet}}中。
application路由是每個Ember應用的固定一部分,所以你不需要再app/router.js人爲的去設置它。
Index路由
在嵌套路由的每一層(包括最頂層路由),Ember會自動的提供一個路由映射到 “/”,並且命名爲index。如果你想了解在哪層有嵌套,打開router,如果你在this.route()中看到了一個function(){},那麼這裏是嵌套。
比如,你寫了個簡單的路由:
app/router.js
Router.map(function() {
this.route('favorites');
});
它等價於:
app/router.js
Router.map(function() {
this.route('index', { path: '/' });
this.route('favorites');
});
index模板將會被渲染到application模板的{{outlet}}中,如果用戶導航到/favorites,Ember將會用favorites模板替換掉index模板。
嵌套路由長這樣:
app/router.js
Router.map(function() {
this.route('posts', function() {
this.route('favorites');
});
});
上面的定義等價於:
app/router.js
Router.map(function() {
this.route('index', { path: '/' });
this.route('posts', function() {
this.route('index', { path: '/' });
this.route('favorites');
});
});
如果用戶導航到/posts,那麼當前的路由會是posts.index,並且posts.index模板將會被渲染到posts模板的{{outlet}}中。
如果用戶接着又導航到/posts/favorites,Ember會將posts/favorites模板渲染,然後用它代替index模板。
動態段
路由負責的事情之一是讀取模型數據。
比如,我們現在有個路由:this.route(‘posts’),那麼這個路由弄不好會把所有的帖子都讀取過來。
這是因爲/posts代表了一個固定的模型,我們沒有添加可以讓它進行檢索的附加信息。然而,如果我們需要一個僅代表某一個帖子的路由,我們就不能再路由中以這樣的形式硬編碼了。
動態段是URL的一部分,以”:”冒號開始,以一個標識符結束:
app/router.js
Router.map(function() {
this.route('posts');
this.route('post', { path: '/post/:post_id' });
});
這個時候,如果用戶導航到/post/5,那麼路由將會將5代替post_id從而讀取到對應的那個帖子。Ember遵守這個約定(:model-name_id)出於2個目的:
- 如果你遵從這個約定,那麼路由將會明白如何拉去正確的模型數據。
- params是一個對象,並且一個key只能關聯一個值。
將以下形式用於代碼中,將不會正確運行:
app/router.js
Router.map(function() {
this.route('photo', { path: '/photo/:id' }, function() {
this.route('comment', { path: '/comment/:id' });
});
});
但是下面這樣可以:
app/router.js
Router.map(function() {
this.route('photo', { path: '/photo/:photo_id' }, function() {
this.route('comment', { path: '/comment/:comment_id' });
});
});
通配符/全局路由
你可以定義通配符路由用以匹配多個URL動態段。你可以這麼用,比如,當用戶進入了某些不存在於你app的URL,那麼你可以通過通配符路由來捕捉所有的這些不存在的URL。通配符路由以星號開頭:
app/router.js
Router.map(function() {
this.route('not-found', { path: '/*path' });
});
app/templates/not-found.hbs
<p>Oops, the page you're looking for wasn't found</p>
在上面的例子中,我們成功了處理了對應用中不存在的URL的訪問,所以當用戶導航到一個不存在的路徑的**path路徑的時候,就會給他顯示一個提示信息。
路由處理程序
爲了讓路由在模板渲染之前做些什麼,你需要創建一個路由處理程序。本章後續的教程中會陸續向你揭示路由處理程序的各種功用。更多關於路由信息,詳見API文檔:the router和route handlers。
本節完