- Ember.js 指南
- 入门指南 - 介绍
- 入门指南 - 应用规划
- 入门指南 - 创建静态页面
- 入门指南 - 获取Ember.js和相应依赖
- 入门指南 - 添加第一个路由与模板
- 入门指南 - 建立模型
- 入门指南 - 使用静态数据
- 入门指南 - 显示模型数据
- 入门指南 - 显示模型的完成状态
- 入门指南 - 创建新的模型实例
- 入门指南 - 标记模型为完成或未完成
- 入门指南 - 显示未完成待办事项的数量
- 入门指南 - 切换显示和编辑状态
- 入门指南 - 接受修改
- 入门指南 - 删除模型
- 入门指南 - 添加子路由
- 入门指南 - 显示未完成待办事项
- 入门指南 - 显示已完成待办事项
- 入门指南 - 显示所有待办事项
- 入门指南 - 添加移除所有已完成待办事项的按钮
- 入门指南 - 提示所有待办事项已完成
- 入门指南 - 切换已完成和未完成待办事项
- 入门指南 - 更换FixtureAdapter
- 获取 Ember - 获取Ember
- 概念 - 核心概念
- 概念 - 命名惯例
- 对象模型 - 类与实例
- 对象模型 - 计算属性
- 对象模型 - 计算属性和带@each的集合数据
- 对象模型 - 观察器
- 对象模型 - 绑定
- 对象模型 - 重新打开类和实例
- 对象模型 - 绑定,观察器,计算属性:如何选择?
- 应用 - 介绍
- 模板 - 应用模板
- 模板 - Handlebars基础
- 模板 - 条件表达式
- 模板 - 显示项目列表
- 模板 - 切换作用域
- 模板 - 绑定元素属性
- 模板 - 绑定元素类名称
- 模板 - 链接
- 模板 - 操作
- 模板 - 输入助手
- 模板 - 开发助手
- 模板 - 用助手来渲染
- 模板 - 编写助手方法
- 路由 - 介绍
- 路由 - 定义路由
- 路由 - 生成的对象
- 路由 - 指定路由的模型
- 路由 - 设置控制器
- 路由 - 渲染模板
- 路由 - 重定向
- 路由 - 指定地址API
- 路由 - 查询参数
- 路由 - 异步路由
- 路由 - 加载中/错误子状态
- 路由 - 阻止和重试过渡
- 组件 - 介绍
- 组件 - 定义组件
- 组件 - 传递属性
- 组件 - 包裹内容
- 组件 - 自定义组件元素
- 组件 - 使用Action处理用户交互
- 组件 - 从组件发送操作给应用
- 控制器 - 介绍
- 控制器 - 代表单一模型
- 控制器 - 代表多模型
- 控制器 - 管理控制器间的依赖
- 模型 - 介绍
- 模型 - 定义模型
- 模型 - 创建和删除记录
- 模型 - 将记录推入仓库
- 模型 - 持久化记录
- 模型 - 查询记录
- 模型 - 使用记录
- 模型 - 使用Fixture
- 模型 - 连接HTTP服务器
- 模型 - 处理元数据
- 模型 - 自定义适配器
- 模型 - 常见问题
- 视图 - 介绍
- 视图 - 定义视图
- 视图 - 处理事件
- 视图 - 在模板中插入视图
- 视图 - 为视图添加布局
- 视图 - 自定义视图元素
- 视图 - 内置视图
- 视图 - 手动管理视图层级
- 枚举 - 介绍
- 测试 - 介绍
- 测试 - 集成测试
- 测试 - 测试助手
- 测试 - 测试用户交互
- 测试 - 单元测试
- 测试 - 单元测试基础
- 测试 - 测试组件
- 测试 - 测试控制器
- 测试 - 测试路由
- 测试 - 测试模型
- 测试 - 自动化测试
- 配置Ember.js - 禁用基本类型扩展
- 配置Ember.js - 嵌入式应用
- 配置Ember.js - 特性标识
- Cookbook - 简介
- Cookbook - 用户界面与交互
- Cookbook - 事件处理和数据绑定
- Cookbook - 助手与组件
- Cookbook - 使用对象
- 理解Ember.js - 视图层
- 理解Ember.js - 管理异步
- 理解Ember.js - 模板自动更新
- 理解Ember.js - 调试
- 理解Ember.js - 运行循环
路由 - 定义路由
英文原文: http://emberjs.com/guides/routing/defining-your-routes/
当启动你的应用时,路由器会负责展示模板,载入数据,以及设置应用状态等任务。 这些都是通过将当前的URL与你定义的路由进行匹配来实现的。
1 2 3 4 | App.Router.map(function() { this.route("about", { path: "/about" }); this.route("favorites", { path: "/favs" }); }); |
现在当用户访问/about
时,Ember.js就会渲染about
的模板。访问/favs
将渲染favorites
的模板。
提示:如果路径(path)的名字跟路由(route)的名字是一样的话,你可以不用写上路径。 所以下面的示例跟上面的是相同的。
1 2 3 4 | App.Router.map(function() { this.route("about"); this.route("favorites", { path: "/favs" }); }); |
在模板里面,你可以用{{link-to}}
来导向路由,这需要用到你在route
方法中定义的名字 (对于/
来说,名字就是index
)。
1 2 3 4 5 6 | {{#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
的类名(class)来指出当前活跃的路由。
你也可以通过创建一个Ember.Route
的子类来对路由的行为进行自定义。例如,创建 App.IndexRoute
类来定义当用户访问/
时会发生什么。
1 2 3 4 5 6 | App.IndexRoute = Ember.Route.extend({ setupController: function(controller) { // Set the IndexController's `title` controller.set('title', "My App"); } }); |
IndexController
是index
模板初始的上下文环境。如果你已经设置了title
, 那么你可以在模板里面使用它。
1 2 | <!-- get the title from the IndexController --> <h1>{{title}}</h1> |
(如果你没有显式的声明IndexController
,Ember.js
会自动生成一个。)
Ember.js
会自动地根据你在this.route
设置的名字来找出对应的路由与控制器。
URL | Route Name | Controller | Route | Template |
---|---|---|---|---|
/ | index | IndexController | IndexRoute | index |
/about | about | AboutController | AboutRoute | about |
/favs | favorites | FavoritesController | FavoritesRoute | favorites |
资源
你可以为一个资源定义一系列的路由:
1 2 3 4 5 | App.Router.map(function() { this.resource('posts', { path: '/posts' }, function() { this.route('new'); }); }); |
跟this.route
一样,如果路径名称跟路由名称相同,你可以忽略路径,所以下面的路由器跟上面是等效的:
1 2 3 4 5 | App.Router.map(function() { this.resource('posts', function() { this.route('new'); }); }); |
这个路由器创建了三个路由:
URL | Route Name | Controller | Route | Template |
---|---|---|---|---|
/ | index | IndexController | IndexRoute | index |
N/A | posts 1 | 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
,等效于跳转到posts.index
或链接到posts.index
。
注意:如果你通过this.resource
定义了一个资源,但是没有提供一个函数作为参数, 那么隐式的resource.index
是不会被创建的。在这种情况下,/resource
只会用到 ResourceRoute
,RescourceController
和resource
模板。
一个资源下的嵌套路由的名字会是资源名加上路由名。如果你想跳转到一个路由(用transitionTo
或 {{#link-to}}
),请确保使用了完整的路由名(如:post.new
,而不是new
)。
正如你期望的一样,访问/
会渲染index
模板。
访问/posts
会有点不同。它会先渲染posts
模板,然后再渲染posts/index
模板到 posts
模板的出口(outlet
)上。
最后,访问/posts/new
会先渲染posts
模板,然后渲染posts/new
模板到它的出口上。
注意:你应该使用this.resource来定义一个URL中的名词字段,而对于用来改变名词字段的形容词或动词字段 ,使用this.route来定义。例如,在上例中的代码,当指定posts
(名词)的URL时,路由被定义为this.resource('posts')
。然而,当定义new
操作(动词)时,那么路由被定义为this.route('new')
。
动态段
在路由处理器的众多职责里,其中有一个就是转换URL并将其传入模型(model
)中。
例如,如果我们有一个资源this.resource('posts')
,那么我们的路由处理器看起来可能像这样:
1 2 3 4 5 | App.PostsRoute = Ember.Route.extend({ model: function() { return this.store.find('post'); } }); |
posts
模板将会接收到一张所有可用的posts清单并将它们当做是上下文环境。
由于/posts
映射到一个特定的模型上,所以我们不需要其他额外的信息就可以运行。然而,如果我们想要路由映射到某个post上,我们可不想通过在路由器中写死每一个可能的post来实现。
探究动态段
一个动态段是URL的一部分,由一个:
起始,后面加上一个标示符组成。
1 2 3 4 5 6 7 8 9 10 | App.Router.map(function() { this.resource('posts'); this.resource('post', { path: '/post/:post_id' }); }); App.PostRoute = Ember.Route.extend({ model: function(params) { return this.store.find('post', params.post_id); } }); |
由于这种模式很常用,所以上面的模型(model
)钩子函数就是默认的行为。
例如,如果动态段是:post_id
,ember.js
会智能地使用App.post
(加上URL
提供的ID
)。 特别地,如果你没有重写了模型(model
),路由将会自动地返回this.store.find('post', params.post_id)
。
这不是巧合,而是Ember Data
所想要的。所以如果你使用Ember
路由和Ember Data
, 你的动态段将会以默认的方式工作。
如果模型没有在URL中使用id
属性,那么应该在路由中定义一个序列化方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | App.Router.map(function() { this.resource('post', {path: '/posts/:post_slug'}); }); App.PostRoute = Ember.Route.extend({ model: function(params) { // the server returns `{ slug: 'foo-post' }` return jQuery.getJSON("/posts/" + params.post_slug); }, serialize: function(model) { // this will make the URL `/posts/foo-post` return { post_slug: model.get('slug') }; } }); |
缺省的serialize
方法将模型的id
插入到路由的动态段中(上述的:post_id
)。
嵌套资源
你不能嵌套路由,但是你可以嵌套资源:
1 2 3 4 5 6 7 8 | App.Router.map(function() { this.resource('post', { path: '/post/:post_id' }, function() { this.route('edit'); this.resource('comments', function() { this.route('new'); }); }); }); |
这个路由器创建了五个路由:
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 |
2 :post_id
就是post的id。例如一个post的id是1,那么路由就是/post/1
comments
模板会被渲染进post
的出口。 所有在comments
下的模板(comments/index
和 comments/new
)都会被渲染进comments
出口。
为了保护路由的命名空间,可以添加深层嵌套的资源:
1 2 3 4 5 6 7 | App.Router.map(function() { this.resource('foo', function() { this.resource('foo.bar', { path: '/bar' }, function() { this.route('baz'); // This will be foo.bar.baz }); }); }); |
上面定义的路由器会创建如下路由:
URL | 路由名称 | 控制器 | 路由 | 模板 |
---|---|---|---|---|
/ | index | App.IndexController | App.IndexRoute | index |
/foo | foo.index | App.FooIndexController | App.FooIndexRoute | foo/index |
/foo/bar | foo.bar.index | App.FooBarIndexController | App.FooBarIndexRoute | foo/bar/index |
/foo/bar/baz | foo.bar.baz | App.FooBarBazController | App.FooBarBazRoute | foo/bar/baz |
初始路由
一些路由在应用创建后便存在:
应用启动时,首先进入
App.ApplicationRoute
,它将渲染application
模板。App.IndexRoute
是默认路由,当用户访问/
时,将渲染index
模板(除非/
被自定义的路由覆盖)。请记住,这些路由是每个应用的一部分,因此不需要在
App.Router.map
中指定。
通配符路由
可以定义通配符路由来匹配多个路由。这种方法很有用,比如如果想获取用户进入应用的错误路由的时候。
1 2 3 | App.Router.map(function() { this.route('catchall', {path: '/*wildcard'}); }); |
通配符路由与动态路由一样,在使用{{link-to}}或者
transitionTo`来进入这个路由的时候,需要提供一个上下文。
1 2 3 4 5 6 7 | App.ApplicationRoute = Ember.Route.extend({ actions: { error: function () { this.transitionTo('catchall', "application-error"); } } }); |
在上述代码中,如果一个错误冒泡到应用路由,那么应用将进入catchall
路由,并在URL中显示/application-error
。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论