Ember.js 概念详解--路由器
用户与你的应用交互,会产生很多不同的状态。框架提供了管理这些状态的有用的工具。
在框架中,应用中每个可能的状态都体现在URL上,并且由路由器负责管理这些状态。路由器下有一组路由,每个路由对应一个状态,也就是一个URL。
当你的应用启动,路由器负责显示模版,加载数据和设置应用状态。它通过匹配当前的URL到你定义的路由来完成工作。
3.3.1 配置路由器
App.Router.map(function() { this.route("about", { path: "/about" }); this.route("favorites", { path: "/favs" });}); 当用户访问 / ,框架会渲染 index 模版。访问 /about 渲染 about 模版,访问 /favs 渲染favorites 模版。当path与路由名相同,就可以省略path。上例等价于 App.Router.map(function() { this.route("about"); this.route("favorites", { path: "/favs" });}); 在你的模版里,可以通过{{linkTo}}标记指定路由名在路由间导航。(/路径的名字是index)
{{#linkTo"index"}}<imgclass="logo">{{/linkTo}}<nav> {{#linkTo"about"}}About{{/linkTo}} {{#linkTo"favorites"}}Favorites{{/linkTo}}</nav> 关于{{linkTo}}的详细请看3.4.5。
3.3.2 定义路由
你可以通过创建一个Ember.Route的子类来自定义路由的行为。例如,定制当用户访问 / 时的行为,创建App.IndexRoute App.IndexRoute = Ember.Route.extend({ setupController: function(controller) { // Set the IndexController's `title` controller.set('title', "My App"); }}); IndexController是index模版的首选上下文。现在你已经设置了title,你可以在模版中使用
<!-- get the title from the IndexController --><h1>{{title}}</h1> (如果你没有定义App.IndexController,框架会自动创建一个。)
框架会根据传给this.route的名字来自动计算路由、控制器、模版的名字。
URL
Route Name
Controller
Route
Template
/
index
IndexController
IndexRoute
index
/about
about
AboutController
AboutRoute
about
/favs
favorites
FavoritesController
FavoritesRoute
favorites
3.3.3 资源
你可以用resources来定义一个路由组。
和this.route一样。path与资源名一样的时候,可以省略path,所以上面的等价于
这个路由器会创建四个路由
URL
Route Name
Controller
Route
Template
/
index
IndexController
IndexRoute
index
N/A
posts1
PostsController
PostsRoute
posts
/posts
posts.index
PostsController
↳PostsIndexController
PostsRoute
↳PostsIndexRoute
posts
↳posts/index
/posts/new
posts.new
PostsController
↳PostsNewController
PostsRoute
↳PostsNewRoute
posts
↳posts/new
1跳转或者链接到posts的行为会被自动重定向到posts.index
注意:如果你配置一个资源但是不提供一个function,那么框架不会创建resource.index路由。这种情况下,/resource会使用ResourceRoute,ResourceController和resource模版。这时this.resource等价于this.route
资源中内嵌的路由的全名要把资源名加在它的名字前(posts.new不是new)。如果你要跳转到一个路由(无论是通过transitionTo或者{{#linkTo}}),确保使用全名(posts.new不是new)。
访问 / 时,跟上面将的规则一样,会渲染 index 模版。
访问 /posts 就有些不一样了。首先会渲染 posts 模版。然后会渲染posts/index 模版到posts模版的outlet中。
访问 posts/new 也会先渲染 posts 模版。然后会渲染 posts/new 模版到posts模版的outlet中。
注意:你应该用名词表示一个资源,资源内的route用形容词或者动词修饰这个名词。
3.3.4 动态参数
动态参数以“:”开头,后面跟着参数名。
App.Router.map(function() {
this.resource('posts');
this.resource('post', {path:'/post/:post_id' });
});
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
},
serialize: function(post) { return { post_id: post.get('id') }; }
});
你的路由的model方法传递参数:post_id到模型里。serialize方法转换模型对象到URL参数中。 (例如:计算一个模型的链接的时候).
因为这种模式很常见,所以路由提供了默认的处理。
· 如果你的动态参数以"_id"结束,model方易做图转换参数post_id的第一部分为应用的命名空间下的一个模型类(post变成App.Post)。然后调用类的find方法,并传入动态参数值。
· 默认的serialize方易做图用模型的id属性值给动态参数赋值。所以上面的serialize方法可以省略。
3.3.5 嵌套资源
你不能在路由中嵌套路由,但是可以在资源中嵌套资源。
这个路由器生成以下路由:
URL
Route Name
Controller
Route
Template
/
index
App.IndexController
App.IndexRoute
index
N/A
post
App.PostController
App.PostRoute
post
/post/:post_id2
post.index
App.PostIndexController
App.PostIndexRoute
post/index
/post/:post_id/edit
post.edit
App.PostEditController
App.PostEditRoute
post/edit
N/A
comments
App.CommentsController
App.CommentsRoute
comments
/post/:post_id/comments
comments.index
App.CommentsIndexController
App.CommentsIndexRoute
comments/index
/post/:post_id/comments/new
comments.new
App.CommentsNewController
App.CommentsNewRoute
comments/new
3.3.6 指定模型
如果你没有动态参数,你需要自己实现model方法,指定使用哪个模型关联匹配的url。
App.Router.map(function() {
this.resource('posts');
});
App.PostsRoute = Ember.Route.extend({
model: function() {
return App.Post.find();
}
});
如果用到动态参数,你会想要通过参数来获取模型。
App.Router.map(function() {
this.resource('post', {path:'/posts/:post_id' });
});
App.PostRoute = Ember.Route.extend({
model: function(params) {
return App.Post.find(params.post_id);
}
});
因为这种模式太常见,上面的model方法就是默认行为。
例如,你的动态参数是post_id,框架会使用_前的post为模型也就是App.Post。除非你重写model方法,否则路由会自动返回App.Post.find(params.post_id)。
3.3.7 设置控制器
在框架中,模版从控制器中获取信息并显示出来。
框架中有两个内置的控制器,Ember.ObjectController和 Ember.ArrayController。它们很好用。它们代理模型的属性,并且有自己的额外的属性,最终传递给模版。
在setupC
补充:web前端 , JavaScript ,