Ember.js 概念详解--路由器
来源:互联网 发布:淘宝左侧排名收费 编辑:程序博客网 时间:2024/05/18 00:42
官方文档地址:http://emberjs.com/guides/routing/
由于是从word考过来的,格式不是太好,大家可以直接去下载我的完整word。里面除了翻译还有原创内容。
http://download.csdn.net/detail/kevinwon1985/5230326
----------------------------------------------------------------------------------------------------
用户与你的应用交互,会产生很多不同的状态。框架提供了管理这些状态的有用的工具。
在框架中,应用中每个可能的状态都体现在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。它们很好用。它们代理模型的属性,并且有自己的额外的属性,最终传递给模版。
在setupController方法中,设置控制器的content属性来代理模型。
App.Router.map(function() {
this.resource('post', {path:'/posts/:post_id' });
});
App.PostRoute = Ember.Route.extend({
setupController:function(controller, model) {
controller.set('content', model);
}
});
setupController方法接收两个参数,第一个是该路由关联的控制器,第二个是model方法返回的模型。上面的例子中,PostRoute的关联控制器是App.PostController的实例。
setupController方法的默认行为就是上面代码。所以你可以省略上面的setupController。
如果你不只是想操作关联的控制器,可以用controllerFor方法。
App.PostRoute = Ember.Route.extend({
setupController: function(controller, model) {
this.controllerFor('topPost').set('content', model);
}
});
3.3.8 渲染模版
路由的一个重要工作就是渲染指定的模版到屏幕。
默认的,会渲染关联的模版到最近的父模版的outlet中,并使用关联的控制器。
App.PostsRoute = Ember.Route.extend({
renderTemplate: function(controller, model) {
this.render();
}
});
包含全部的参数的代码如下
App.PostsRoute = Ember.Route.extend({
renderTemplate:function(controller, model) {
this.render('posts', { //模版名,默认是关联的posts
into:undefined, //父模版,没有就是undefined
outlet:'main', //outlet名字,默认是main,也就是父模版中的唯一的没有命名outlet
controller:'posts'//默认是PostsController控制器,可以直接传控制器实例
});
}
});
3.3.9 重定向
如果你先重定向到另外一个路由,需要实现redirect方法。
App.Router.map(function() {
this.resource('posts');
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('posts');
}
});
你也可以基于应用关状态添加重定向条件。
App.Router.map(function() {
this.resource('topCharts',function() {
this.route('choose', {path:'/' });
this.route('albums');
this.route('songs');
this.route('artists');
this.route('playlists');
});
});
App.TopChartsChooseRoute = Ember.Route.extend({
redirect: function() {
var lastFilter = this.controllerFor('application').get('lastFilter');
this.transitionTo('topCharts.' + lastFilter ||'songs');
}
});
// Superclass to be used by all of the filter routes below
App.FilterRoute = Ember.Route.extend({
enter: function() {
var controller = this.controllerFor('application');
controller.set('lastFilter',this.templateName);
}
});
App.TopChartsSongsRoute = App.FilterRoute.extend();
App.TopChartsAlbumsRoute = App.FilterRoute.extend();
App.TopChartsArtistsRoute = App.FilterRoute.extend();
App.TopChartsPlaylistsRoute = App.FilterRoute.extend();
如果路由的redirect钩子方法没有重定向到另外的路由,余下的钩子方法(model,setupController,renderTemplate)还是会执行。
3.3.10指定url类型
路由器默认使用浏览器url的哈希值来加载应用的初始状态,并且在url地址发生改变是同步状态。目前,这些是通过浏览器的hashchange来实现的。
看下面的路由器。当你访问/#/posts/new会关联到进入posts.new路由。
App.Router.map(function() {
this.resource('posts',function() {
this.route('new');
});
});
如果你先使用地址/posts/new替代/#/posts/new,你需要告诉路由使用浏览器的history API。
App.Router.reopen({
location: 'history'
});
如果你不想浏览器的url与你的应用交互,可以完全禁用location API。这有助于你测试,或者在不想改变url的情况下用路由器管理应用状态(例如当把应用嵌入到一个更大的页面中)。
App.Router.reopen({
location: 'none'
});
上一篇: Ember.js 指引--命名约定
- Ember.js 概念详解--路由器
- Ember.js 概念详解--模型
- Ember.js 指引--核心概念
- ember.js
- Ember学习(1):Ember核心概念
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
- MVC、MVP、MVVM、Angular.js、Knockout.js、Backbone.js、React.js、Ember.js、Avalon.js、Vue.js 概念摘录
- Ember.js常用函数
- ember.js教程
- Ember.js学习总结
- Ember.js实战
- Ember.js--入门
- Ember.js学习笔记
- Ember.js学习笔记
- Ember.js 指引--命名约定
- Ember.js 的初学者指南
- Ember.js 的初学者指南
- 关于 Ember.js 1.X
- 将JavaWeb项目部署到Tomcat根目录下
- OPhone设置、获取振铃和短信音
- JavaScript初学者最容易犯的错误(二)
- Planning Screens and Their Relationships 规划屏幕和它们的关系
- 手把手教你用GHOST备份还原安装电脑系统详细图文教程
- Ember.js 概念详解--路由器
- Uglifyjs入门
- SQL Server 中 RAISERROR 的用法
- 2013年4月1日
- Hash的JAVA
- qemu学习(二)————qemu中对处理器大小端的设置
- Planning for Multiple Touchscreen Sizes 规划多个触摸屏尺寸
- 2013年4月2日
- 计算机科学中最重要的32个算法