#2 定义路由

英文原版:https://guides.emberjs.com/v2.13.0/routing/defining-your-routes/

当你开始运行你的app时,router会将当前的URL与你定义路由相匹配。这些路由呢,则会负责显示模板,读取数据并且更新app状态。

定义路由,命令:

ember generate route route-name

这个命令创建了个一个路由源文件:app/routes/route-name.js,一个模板文件:app/templates/route-name.hbs和一个单元测试文件:tests/unit/routes/route-name-test.js。并且会在app/router.js中添加一条路由信息。

基本路由

Ember应用的app/router.js中的map()方法会被调用,用来生成路由映射。当调用map()时,你需要给它传一个函数,并且在函数内需要通过this.route()来定义路由。

app/router.js

Router.map(function() {
  this.route('about', { path: '/about' });
  this.route('favorites', { path: '/favs' });
});

好了,现在如果用户访问 /about 路由,Ember将会渲染about模板;若访问/favs,则会渲染 favorites 模板。

当然如果路由名称与名称对象的值一样,你也可以不设置名称对象。下面的这个种方式与上面的例子是等价的:

app/router.js

Router.map(function() {
  this.route('about');
  this.route('favorites', { path: '/favs' });
});

在模板中,你可以使用{{link-to}}助手来在这这些路由之间进行导航。助手中的路由参数值,只需要跟你在router中定义的router()方法的第一各参数一致即可:

{{#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类,用来标示当前正在访问的路由。

多词名称路由,需要你用减号来作为每个单词的分隔符:

app/router.js

Router.map(function() {
  this.route('blog-post', { path: '/blog-post' });
});

上面定义的这个路由,默认会使用blog-post.js作为它的处理程序,blog-post.hbs作为模板,并且在{{link-to}}助手中通过blog-post来引用。

你可以可以使用下面这种方式来命名多词路由:

app/router.js

Router.map(function() {
  this.route('blog_post', { path: '/blog-post' });
});

这种方式仍然会以blog-post.js作为它的处理程序、blog-post.hbs作为模板。但是,在{{link-to}}助手中需要使用blog_post来引用

嵌套路由

你尝尝也会需要使模板可以显示它下层的其他模板。比如,在一个博客应用中,相对于在 一堆的博客列表中有个创建博客的区域,或许你更倾向于在列表页的下一页专门弄个创建博客的页面。

这个时候,嵌套路由就用上了。

定义嵌套路由只需要在this.route中添加一个回调函数:

app/router.js

Router.map(function() {
  this.route('posts', function() {
    this.route('new');
  });
});

这里假设你已经生成了post路由,为了生成它的嵌套路由,你可以运行下面的命令:

ember generate route posts/new

然后,在post路由中放一个 {{outlet}},用来在上层路由中显示嵌套路由:

templates/posts.hbs

<h1>Posts</h1>
<!-- Display posts and other content -->
{{outlet}}

router会创建一个/posts映射和一个/posts/new映射。当用户访问/posts时,他们只会看见posts.hbs模板中的内容(注意了,回忆下之前说过的index路由)。只有当用户访问posts/new时,posts/new.hbs模板才会被渲染并出现在{{outlet}}所在位置,紧接着才会在页面上出现。

嵌套路由的名字中包含它的祖先路由的名字。如果你想跳转到其他路由(通过transitionTo或{{#link-to}}实现挑破转),请确保使用完整的路由名称,例如: 使用posts.new 而不是new

application路由

当你的应用第一次启动的时候,那么将会首先进入application路由。如果其他路由一样,所读取的模板也是application。你可以将你的网站的header,footer或者其他始终显示在页面的内容放在application.hbs中。其他路由的模板将会最终将会被渲染到application.hbs模板的{{outlet}}中。

application路由是每个Ember应用的固定一部分,所以你不需要再app/router.js人为的去设置它。

Index路由

在嵌套路由的每一层(包括最顶层路由),Ember会自动的提供一个路由映射到 “/”,并且命名为index。如果你想了解在哪层有嵌套,打开router,如果你在this.route()中看到了一个function(){},那么这里是嵌套。

比如,你写了个简单的路由:

app/router.js

Router.map(function() {
  this.route('favorites');
});

它等价于:

app/router.js

Router.map(function() {
  this.route('index', { path: '/' });
  this.route('favorites');
});

index模板将会被渲染到application模板的{{outlet}}中,如果用户导航到/favorites,Ember将会用favorites模板替换掉index模板。

嵌套路由长这样:

app/router.js

Router.map(function() {
  this.route('posts', function() {
    this.route('favorites');
  });
});

上面的定义等价于:

app/router.js

Router.map(function() {
  this.route('index', { path: '/' });
  this.route('posts', function() {
    this.route('index', { path: '/' });
    this.route('favorites');
  });
});

如果用户导航到/posts,那么当前的路由会是posts.index,并且posts.index模板将会被渲染到posts模板的{{outlet}}中。

如果用户接着又导航到/posts/favorites,Ember会将posts/favorites模板渲染,然后用它代替index模板。

动态段

路由负责的事情之一是读取模型数据。

比如,我们现在有个路由:this.route(‘posts’),那么这个路由弄不好会把所有的帖子都读取过来。

这是因为/posts代表了一个固定的模型,我们没有添加可以让它进行检索的附加信息。然而,如果我们需要一个仅代表某一个帖子的路由,我们就不能再路由中以这样的形式硬编码了。

动态段是URL的一部分,以”:”冒号开始,以一个标识符结束:

app/router.js

Router.map(function() {
  this.route('posts');
  this.route('post', { path: '/post/:post_id' });
});

这个时候,如果用户导航到/post/5,那么路由将会将5代替post_id从而读取到对应的那个帖子。Ember遵守这个约定(:model-name_id)出于2个目的:

  1. 如果你遵从这个约定,那么路由将会明白如何拉去正确的模型数据。
  2. params是一个对象,并且一个key只能关联一个值。

将以下形式用于代码中,将不会正确运行:

app/router.js

Router.map(function() {
  this.route('photo', { path: '/photo/:id' }, function() {
    this.route('comment', { path: '/comment/:id' });
  });
});

但是下面这样可以:

app/router.js

Router.map(function() {
  this.route('photo', { path: '/photo/:photo_id' }, function() {
    this.route('comment', { path: '/comment/:comment_id' });
  });
});

通配符/全局路由

你可以定义通配符路由用以匹配多个URL动态段。你可以这么用,比如,当用户进入了某些不存在于你app的URL,那么你可以通过通配符路由来捕捉所有的这些不存在的URL。通配符路由以星号开头:

app/router.js

Router.map(function() {
  this.route('not-found', { path: '/*path' });
});
app/templates/not-found.hbs

<p>Oops, the page you're looking for wasn't found</p>

在上面的例子中,我们成功了处理了对应用中不存在的URL的访问,所以当用户导航到一个不存在的路径的**path路径的时候,就会给他显示一个提示信息。

路由处理程序

为了让路由在模板渲染之前做些什么,你需要创建一个路由处理程序。本章后续的教程中会陆续向你揭示路由处理程序的各种功用。更多关于路由信息,详见API文档:the routerroute handlers

本节完

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值