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'));
}
}
});