1.Basic Routes
1.1 Router.map()
Map() 方法用來規定一個URL應該返回哪個route。
Router.map(function() {
this.route('about', { path: '/about' });
this.route('favorites', { path: '/favs' });
});
當路徑與route名稱相同時,可以省略路徑。
在模板中,{{link-to}} 來設置路由跳轉。
1.1 創建內聯Route(nested route)
router.js() {
this.route(‘posts’,function() {
this.route(“new”);
}
}
使用命令ember g route posts/new 來自動創建二級路由new。
(需要安裝ember-cli)
然后在模板中(Templates) 要顯示二級路由new的地方,增加 {{outlet}}。
當用戶訪問 posts 路由時,posts 別渲染出來,當用戶訪問new路由時,ember將在
{{outlet}} 的地方渲染出new 的templetas。
字路由的名字包括他父路由的名字,當調用到二級路由時(transitionTo 或這{{outlet}} ) ,注意名字應為全名,例如,應為posts.new,而不是new。
每個路由都有一個默認的index路由,如果你定義了一個路由的二級路由,那么當用戶訪問這個路由時,Ember會渲染這個路由的index路由,如果用戶訪問了這個路由另一個字路由,那么Ember就會將index子路由替換為當前訪問的子路由。
例如:
Router.map(function) {
This.route(‘index’,{path: ’/’});
This.route (‘post’,function() {
This.route(‘index’,{path: ‘/’});
This.route(‘new’,{path: ‘new’});
)};
});
當用戶訪問post路由時,ember渲染 post.index ,當用戶訪問/post/new 時,ember渲染post.new。也就是將Templete中{{outlet}}地方的渲染從index路由 替換成了 new路由。
1.2 Dynamic Segments動態細分
路由的一個作用是加載一個model。
比如有一個路由是posts,它加載所有的posts model
但是,當我們想要加載某一篇post的時候,應該怎么辦呢
這時就用到了 Dynamic Segments
,它是URL的一部份,以:
開始,后邊跟著一個識別符。
比如/comment/:comment_id
1.3 globbing routes
通配符的路由
globbing route
的意識就是,可以定義一個路由,來匹配多個路徑。
我們可以用這樣的路由來應對用戶進入不該進入的路徑的情況。
通配路由以一個asterisk
(星號)開始,例如
this.route(‘not-found’, { path: ‘/*path’ });
1.4 Route Handlers路由處理器
可以來創建一個RouterHandlers來讓Route實現除了返回同名字的Template的其他功能。
具體如何創建一個路由處理器,參考官方API文檔 The Route 和 Route Handlers。
2. Specifying a Route's Model / 確定一個路由模型
我們可以使用 model()
hook 來使 favorite-posts
路由加載相應的post
。
例如:
import Route from '@ember/routing/route';
export default Route.entend({
model () {
return this.get('store').query('post', { favorite: true});
}
})
通常,model hook
應該返回一個 Ember data
,但是它也可以返回任何形式的 promise
的對象(或數組),Ember
會一直等待,知道lodading finished
或者 promise
完成。
之后,路由會將model
返回的值設置為model
的屬性(property),然后我們就可以在模板(template
)中使用model
屬性了。
例如:
<h1>Favorite Routs</h1>
{{#each model as |post|}}
<p>{{post.body}}</p>
{{/each}}
3. Render a Template / 渲染模板
路由的一個作用是將合適的模板渲染到屏幕上,默認情況下,路由會將相同名字的模板渲染出來。
例如:
Router.map(function() {
this.route( 'posts' , function () {
this.route('new');
})
})
post
路由會渲染post.hbs
模板,posts.new
會渲染post/new.hbs
模板。
每個模板,都會被渲染到它的父路由的模板的{{outlet}}
標簽處。
可以通過設定模板標簽名稱的方式,來進一步控制模板的渲染。
例如:
import Route from '@ember/routing/route';
export default Route.extend({
templateName: 'posts/favorite-posts'
});
我們也可以通過重載 randerTemplate()
方法來控制模板的渲染。
4. Redirecting / 重定向
當用戶嘗試訪問不能訪問的頁面時,我們需要將用戶訪問的頁面重定向到我們設定好的頁面,比如登陸頁面或者首頁等。
4.1 路由中定義重定向
可以使用transitionTo()
方法和replaceWith()
方法來進行路由的重定向。
這兩個方法唯一的不同在于,transitionTo()
是離開當前的路由,然后渲染一個新的路由。而replaceWith()
是將當前路由替換為重定向重定向的路由。這個差別體現在對網站訪問的歷史的影響不同。
4.2 在controller
中設置重定向
在controller
中設置路由重定向則使用transitionTo()
方法。
5. 在路由執行之前重定向
我們一般希望用戶訪問沒有權限的路由時,此路由不渲染然后立馬重定向到我們設置好的路由。
這時可以在beforeModel()
中定義路由重定向,這樣就能在路由渲染之前實現重定向了。
6. 在路由執行之后重定向
有時候我們需要知道當前路由的一些信息來決定應該重定向到哪個路由上去。
這時應該在afterModel()
中定義路由重定向。
它有兩個參數,一個是當前的路由,另一個是重定向的路由。
例如:
import Route from '@ember/routing/route';
export default Route.extend({
afterModel(model, transition) {
if (model.get('length') === 1) {
this.transitionTo('post', model.get('firstObject'));
}
}
});