路由和模板

优质
小牛编辑
135浏览
2023-12-01

对于Super Rentals,我们希望首先到达home页面,在上面显示租赁列表,然后可以跳转到about页面和contact页面。(下列测试在/opt/super-rentals目录下进行)

about路由

生成about路由:

$ ember generate route about
installing route
  create app/routes/about.js
  create app/templates/about.hbs
updating router
  add route about
installing route-test
  create tests/unit/routes/about-test.js

一个Ember路由由三部分组成:

  • 一个在Ember路由(app/router.js)中的条目,它会将路由名称映射到一个特定URI(或者反过来映射)
  • 一个路由处理文件(如app/routes/about.js),定义路由被加载时发生什么
  • 一个路由模板(如app/templates/about.hbs),定义显示的内容 打开app/router.js看看,发现多了下面的代码:
    Router.map(function() {
    this.route('about');
    });
    

    上述代码告诉Ember路由,当访问URI/about时运行app/routes/about.js文件。
    然后打开模板文件app/templates/about.hbs,修改为下列内容:

    <div class="jumbo">
    <div class="right tomster"></div>
    <h2>About Super Rentals</h2>
    <p>
      The Super Rentals website is a delightful project created to explore Ember.
      By building a property rental site, we can simultaneously imagine traveling
      AND building Ember applications.
    </p>
    </div>
    

    用浏览器访问地址http://c7302.ambari.apache.org:4200/about测试一下about页面。

联系我们路由

生成联系我们路由:

$ ember g route contact

Ember CLI再一次向app/router.js中添加了contact条目,生成了一个路由处理器app/routes/contact.js,以及模板文件app/templates/contact.hbs
向模板文件中添加下列内容:

<div class="jumbo">
  <div class="right tomster"></div>
  <h2>Contact Us</h2>
  <p>Super Rentals Representatives would love to help you<br>choose a destination or answer
    any questions you may have.</p>
  <p>
    Super Rentals HQ
    <address>
      1212 Test Address Avenue<br>
      Testington, OR 97233
    </address>
    <a href="tel:503.555.1212">+1 (503) 555-1212</a><br>
    <a href="mailto:superrentalsrep@emberjs.com">superrentalsrep@emberjs.com</a>
  </p>
</div>

用浏览器访问地址http://c7302.ambari.apache.org:4200/contact可以看到新增加的“联系我们”页面。

链接导航和{ { link-to } }助手

为了方便在页面间跳转,需要在“关于”页面增加一个链接到“联系我们”页面,同样需要在“联系我们”页面增加一个链接到“关于”页面。
为了做到这一点,我们将使用{ { link-to } }这个Ember提供的助手,这样可以轻松地在我们的路由之间进行链接。我们来调整我们的about.hbs文件:

(略)
  { { #link-to 'contact' class="button" } }
    Contact Us
  { { /link-to } }
</div>

在这种情况下,我们告诉{ { link-to } }助手我们要链接到的路由的名称:contact。用浏览器访问地址http://c7302.ambari.apache.org:4200/about,看到页面多了一个链接到“联系我们”页面。
同样,修改app/templates/contact.hbs文件添加到about路由的链接:

(略)
  { { #link-to 'about' class="button" } }
    About
  { { /link-to } }
</div>

租赁清单路由

下面添加一个显示租赁清单的路由(rentals):

$ ember g route rentals

先往租赁清单模板文件(app/templates/rentals.hbs)添加点初始内容,之后再进一步补充:

<div class="jumbo">
  <div class="right tomster"></div>
  <h2>Welcome!</h2>
  <p>We hope you find exactly what you're looking for in a place to stay.</p>
  { { #link-to 'about' class="button" } }
    About Us
  { { /link-to } }
</div>

index路由

index路由用于处理对于网站根URI(/)请求。我们想用租借列表页面(URI是/rentals)充当应用的主页面。因此,我们希望我们的index路由简单地转发到已经创建的rentals路由。
创建index路由:

$ ember g route index
installing route
  create app/routes/index.js
  create app/templates/index.hbs
installing route-test
  create tests/unit/routes/index-test.js

从上面的提示中可以看出,index路由比较特殊,不需要向路由映射(app/router.js)中添加条目。
我们的需求是当用户访问根URI(/)转向到/rentals。为了实现这个需要需要在index路由的处理程序(index.js)中实现一个叫beforeModel路由生命周期钩子函数。
每个路由处理程序都有一组“生命周期钩子”,它们是在加载页面时在特定时间被调用的函数。在beforeModel钩子在数据从模型钩子取出之前执行,也在页面被渲染之前。
在index处理程序中,我们调用replaceWith函数。该replaceWith函数类似于路由的transitionTo函数,区别在于replaceWith将替换浏览器历史中的当前URL,而transitionTo将添加到历史记录中。由于我们希望我们的rentals路由作为我们的主页,我们将使用该replaceWith函数。
将index处理程序(app/routes/index.js)修改成如下的样子:

import Ember from 'ember';

export default Ember.Route.extend({
  beforeModel() {
    this.replaceWith('rentals');
  }
});

现在访问根路由/将导致/rentalsURL的加载。

添加顶部导航

我们希望在所有页面的顶部添加一个通用区域显示应用标题和导航条。
为了完成这个需求,需要修改应用模板(/app/templates/application.hbs)。先看原来的内容:

<h1> This my webcome page .... </h1>
{ { outlet } }

在上面的模板下,应用所有页面的顶部都会显示<h1>This my webcome page .... </h1>,而{ { outlet } }的位置会显示当前路由的网页内容。
为了完成本节需求,需要将应用模板修改成下列的样子:

<div class="container">
  <div class="menu">
    { { #link-to 'index' } }
      <h1>
        <em>SuperRentals</em>
      </h1>
    { { /link-to } }
    <div class="links">
      { { #link-to 'about' } }
        About
      { { /link-to } }
      { { #link-to 'contact' } }
        Contact
      { { /link-to } }
    </div>
  </div>
  <div class="body">
    { { outlet } }
  </div>
</div>

现在通过浏览器访问地址http://c7302.ambari.apache.org:4200/contact可以看到在页面的顶部显示了标题SuperRentals以及aboutcontact两个链接。

实现验收测试

首先,我们要测试访问/是否正确重定向到/rentals。我们将使用Ember visit助手,然后确保我们当前的URL是/rentals重定向发生的。
打开之前创建的验收创建文件/tests/acceptance/list-rentals-test.js,修改为:

(前面的6个test省略)
test('should show rentals as the home page', function (assert) {
  visit('/');
  andThen(function() {
    assert.equal(currentURL(), '/rentals', 'should redirect automatically');
  });
});

原来的currentURL()会等于/,而现在被replaceWith/rentals,所以测试代码要改成上面 运行测试程序:

$ ember test --server

用浏览器访问http://c7302.ambari.apache.org:7357,然后发现7个测试成功了1个,6个失败。如果没有把/修改成/rentals,则7个都失败。

Ember测试助手

Ember提供各种验收测试助手,使常见任务更容易,如访问路由,填写字段,点击链接/按钮,等待页面显示。

我们常用的一些助手是:

  • visit - 加载给定的URL
  • click - 假装是用户点击屏幕的特定部分
  • andThen - 等待之前的命令执行结束,然后执行指定函数。在下面的测试中,我们等待click后页面的加载,然后检查页面是否加载正确
  • currentURL - 返回我们当前所在页面的URL

测试about和contact页面

如果ember test已经在执行,可以打开另外的终端窗口来编辑tests/acceptance/list-rentals-test.js文件,将之前的about和contact两个测试替换成下列代码:

test('should link to information about the company.', function (assert) {
  visit('/');
  click('a:contains("About")');
  andThen(function() {
    assert.equal(currentURL(), '/about', 'should navigate to about');
  });
});

test('should link to contact information', function (assert) {
  visit('/');
  click('a:contains("Contact")');
  andThen(function() {
    assert.equal(currentURL(), '/contact', 'should navigate to contact');
  });
});

Ember test检测到了测试文件的变化,并自动加载。现在7个测试成功了3个,分别是//about/contact