Ember 路由定義

2018-01-06 17:47 更新

當你的應用啟動的時候,路由器就會匹配當前的URL到你定義的路由上。然后按照定義的路由層次逐個加載數(shù)據(jù)、設置應用程序狀態(tài)、渲染路由對應的模板。

1,基本路由

app/router.jsmap方法里定義的路由會映射到當前的URL。當map方法被調用的時候方法體內的route方法就會創(chuàng)建路由。

下面使用Ember CLI命令創(chuàng)建兩個路由:

  1. ember generate route about
  2. ember generate route favorites

命令執(zhí)行完之后你可在你的項目目錄app/routes下面看到已經(jīng)創(chuàng)建好的兩個路由文件已經(jīng)app/templates下面路由對應的模板文件。 此時在app/router.jsmap方法中已經(jīng)存在了剛剛創(chuàng)建的路由配置。這個是Ember CLI自動為你創(chuàng)建了。

  1. // app/router.js
  2. import Ember from 'ember';
  3. import config from './config/environment';
  4. var Router = Ember.Router.extend({
  5. location: config.locationType
  6. });
  7. Router.map(function() {
  8. this.route('about');
  9. this.route('favorites');
  10. });
  11. export default Router;

現(xiàn)在分別修改app/templates下面的兩個模板文件如下:

  1. 這個是about模板!<br>
  2. {{outlet}}
  1. 這個是favorites模板!<br>
  2. {{outlet}}

然后訪問http://localhost:4200/about或者http://localhost:4200/favorites,如果你的程序沒有問題你也會得到如下顯示結果:

run result

如果你覺得favorites這個路由名字太長是否可以修改成其他名字呢?答案是肯定的,你只要修改router.jsmap方法的配置即可。

  1. Router.map(function() {
  2. this.route('about');
  3. // 注意:訪問的URL可以寫favs但是項目中如果是使用route的地方仍然是使用favorites
  4. this.route('favorites', { path: '/favs' });
  5. });

此時訪問:http://localhost:4200/favs,界面顯示的結果與之前是一樣的。

說明:默認情況下訪問的URL與路由名字是一致的,比如this.route('about')this.route('about', { path: ‘/about’ })是同一個路由,如果URL與路由不同名則需要使用{path: '/xxx'}設置映射的URL。

在handlebars模板中可以使用{{link-to}}助手在不同的路由間切換,使用時需要在link-to助手內指定路由名稱。比如下面的代碼使用link-to助手實現(xiàn)在aboutfavs兩個路由間切換。 為了頁面能美觀一點引入bootstrap,使用npm命令安裝:bower install bootstrap,如果安裝成功你可以在bower_components目錄下看到bootstrap相關的文件。安裝成功之后引入到項目中,修改chapter3_routes/ember-cli-build.js。在return語句前加入如下兩行代碼(作用就是引入bootstrap框架):

  1. app.import("bower_components/bootstrap/dist/css/bootstrap.css");
  2. app.import("bower_components/bootstrap/dist/js/bootstrap.js");

修改application.hbs,增加一個導航菜單。

  1. <div class="container-fluid">
  2. <div class="navbar-header" href="#">
  3. {{#link-to 'index' class="navbar-brand"}}Home{{/link-to}}
  4. </div>
  5. <ul class="nav navbar-nav">
  6. <li>{{#link-to 'about'}}about{{/link-to}}</li>
  7. <li>{{#link-to 'favorites'}}favorites{{/link-to}}</li>
  8. </ul>
  9. <ul class="nav navbar-nav navbar-right">
  10. <li><a href="#">Login</a></li>
  11. <li><a href="#">Logout</a></li>
  12. </ul>
  13. </div>
  14. <div class="container-fluid" style="margin-top: 70px;">
  15. {{outlet}}
  16. </div>

如果看到頁面沒有bootstrap效果請重新啟動項目。如果運行項目后再瀏覽器控制臺出現(xiàn)如下錯誤。

run result

如果出現(xiàn)上圖錯誤需要在config/environment.js中加上一些安全策略設置代碼,有關設置的解釋請看下面網(wǎng)址的文章介紹。

  1. ember-cli-and-content-security-policy-cs
  2. https://www.w3.org/TR/2015/CR-CSP2-20150721/
    1. , contentSecurityPolicy: {
    2. 'default-src': "'none'",
    3. 'script-src': "'self' 'unsafe-inline' 'unsafe-eval' use.typekit.net connect.facebook.net maps.googleapis.com maps.gstatic.com",
    4. 'font-src': "'self' data: use.typekit.net",
    5. 'connect-src': "'self'",
    6. 'img-src': "'self' www.facebook.com p.typekit.net",
    7. 'style-src': "'self' 'unsafe-inline' use.typekit.net",
    8. 'frame-src': "s-static.ak.facebook.com static.ak.facebook.com www.facebook.com"
    9. }

配置截圖

上圖是我的演示項目配置。然后點擊about會得到如下界面

result

可以看到瀏覽器地址欄的URL變?yōu)?code>about了,并且頁面顯示的內容也是about模板的內容。同理你點擊favorites地址欄就變?yōu)?a href="http://localhost:4200/favs" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" >http://localhost:4200/favs并且顯示的內容是favorites的(為什么URL是favs而不是favorites呢,因為前面已經(jīng)修改了route和URL的映射關系,路由favorites對應的URL是favs)。 上述演示的就是路由的切換?。?!

可以看到瀏覽器地址欄的URL變?yōu)閍bout了,并且頁面顯示的內容也是about模板的內容。同理你點擊“favorites”地址欄就變?yōu)閔ttp://localhost:4200/favs并且顯示的內容是favorites的(為什么URL是favs而不是favorites呢,因為前面已經(jīng)修改了route和URL的映射關系,路由favorites對應的URL是favs)。 上述演示的就是路由的切換?。?!

2,路由嵌套

還記得在前面的Ember.js 入門指南之十三{{link-to}} 助手這篇文章的內容嗎?在這篇文章中比較詳細的介紹了路由的嵌套與怎么使用嵌套的路由。不妨回過頭去看看。在這里打算就不講了……如果有不明白的請看官網(wǎng)的教程。

3,application路由

application路由是默認的路由,是程序的入口,所有其他自定義的路由都先進過application才到自定義的路由。并且application路由對應的application.hbs模板是所有自定義模板的父模板,所有自定義的模板都會渲染到application.hbs模板的{{outlet}}上。有關于路由的執(zhí)行順序以及模板的渲染順序在前面的Ember.js 入門指南之十三{{link-to}} 助手也講過了,在此也不打算在做過多的介紹了。你可以回頭看之前的文章或者到官網(wǎng)查看。

4,index路由

對于所有的嵌套的路由,包括最頂層的路由Ember會自動生成一個訪問URL為/對應路由名稱為index的路由。

比如下面的兩種路由設置是等價的。

  1. // app/router.js
  2. // ……
  3. Router.map(function() {
  4. this.route('about');
  5. // 注意:訪問的URL可以寫favs但是項目中如果是使用route的地方仍然是使用favorites
  6. this.route('favorites', { path: '/favs' });
  7. });
  8. export default Router;

  1. // app/router.js
  2. // ……
  3. Router.map(function() {
  4. this.route('index', { path: '/' });
  5. this.route('about');
  6. // 注意:訪問的URL可以寫favs但是項目中如果是使用route的地方仍然是使用favorites
  7. this.route('favorites', { path: '/favs' });
  8. });
  9. export default Router;

index路由會渲染到application.hbs模板的{{outlet}}上。這個是Ember默認設置。當用戶訪問/about時Ember會把index模板替換為about模板。

對于路由嵌套的情況也是如此。

  1. // app/router.js
  2. // ……
  3. Router.map(function() {
  4. this.route('posts', function() {
  5. this.route('new');
  6. });
  7. });
  8. export default Router;
  1. // app/router.js
  2. // ……
  3. Router.map(function() {
  4. this.route('index', { path: '/' });
  5. this.route('posts', function() {
  6. this.route('index', { path: '/' });
  7. this.route('new');
  8. });
  9. });
  10. export default Router;

兩種設置方式都會得到如下圖的路由表。打開瀏覽器的“開發(fā)者工具”點開“Ember”選項卡,在點開“/#Routes”你就可以看到如下路由表(顯示是順序有可能跟你的不一樣)。

路由渲染結果

注:loadingerror這兩個路由是ember自動生成的,他們的用法會在后面的文章介紹。

當用戶訪問/posts時實際進入的路由是posts.index對應的模板是posts/index.hbs,但是實際中我并沒有創(chuàng)建這個模板,因為Ember默認把這個模板渲染到posts.hbs{{outlet}}上。由于這個模板不存在也就相當于什么都沒做。當然你也可以創(chuàng)建這個模板。
使用命令:ember generate template posts/index然后在這個模板中添加以下顯示的內容:

  1. <h2>這里是/posts/index.hbs。。。</h2>

再此訪問http://localhost:4200/posts,是不是可以看到增加的內容了。

你可以這么理解對于每一個有子路由的路由都有一個名為index的子路由并且這個路由對應的模板為index.hbs,如果把有子路由的路由當做一個模塊看待那么index.hbs就是這個模塊的首頁。特別是做過一些信息系統(tǒng)的朋友應該是很熟悉的,基本上沒個子模塊都會有一個首頁,這個首頁現(xiàn)實的內容就是一進入這個模塊時就顯示的內容。既然是子模板當然也不會例外它也會渲染到父模板的{{outlet}}上。比如上面的例子當用戶訪問http://localhost:4200/posts實際進入的是http://localhost:4200/posts/(后面多了一個/,這個/對應的模板就是index),當用戶訪問的是http://localhost:4200/posts/new,那么進入的就是posts/new.hbs這個模板(也是渲染到posts.hbs{{outlet}}上)。

4,動態(tài)段

關于動態(tài)段在前面的Ember.js 入門指南之十三{{link-to}} 助手也介紹過了,在這里就再簡單補充下。

路由最主要的任務之一就是加載model。

例如對于路由this.route('posts');會加載項目中所有的posts下的model。但是當你只想加載其中一個model的時候怎么處理呢?而且大多數(shù)情況我們是不需要一次性加載完全部數(shù)據(jù)的,一般情況都是加載其中一小部分。這個時候就需要動態(tài)段了!

動態(tài)段以:開頭,并且后面接著modelid屬性。

  1. // app/router.js
  2. // ……
  3. Router.map(function() {
  4. this.route('about');
  5. // 注意:訪問的URL可以寫favs但是項目中如果是使用route的地方仍然是使用favorites
  6. // this.route('favorites', { path: '/favs' });
  7. this.route('posts', function() {
  8. this.route('post', { path: '/:post_id'});
  9. });
  10. });
  11. export default Router;

此時你可以訪問http://localhost:4200/posts/1,不過我們還沒創(chuàng)建model所以會報錯。這個我們暫時不管,后面會有一章是介紹model的?,F(xiàn)在只要知道你訪問http://localhost:4200/posts/1就相當于獲取id值唯一的model

5,通配符/全局路由

Ember也同樣運行你使用*作為URL通配符。有了通配符你可以設置多個URL訪問同一個路由。

  1. this.route('about', { path: '/*wildcard' });

然后訪問:http://localhost:4200/wildcard或者訪問http://localhost:4200/2423432ffasdfewildcard或者http://localhost:4200/2333都是可以進入到about這個路由,但是http://localhost:4200/posts仍然進入的是posts這個路由。因為可以匹配到這個路由。

6,重置子路由的命名空間

在有路由嵌套的情況下,一般情況我們訪問URL的格式都是父路由名/子路由名,Ember提供了一個resetNamespace:true選項可以用戶重置子路由的命名空間,使用這個設置的路由可以直接這樣訪問/子路由名,不需要寫父路由名。

  1. this.route('posts', function() {
  2. this.route('post', { path: '/:post_id'});
  3. this.route('comments', { resetNamespace: true}, function() {
  4. this.route('new');
  5. });
  6. });

此時如果你想問的new這個路由你可以直接不寫comments。http://localhost:4200/posts/new,而不需要http://localhost:4200/posts/comments/new,不過模板渲染的順序沒變,new模板仍然是渲染到comments{{outlet}}上。

不過個人覺得還是不使用這個設置比較好,特別是在開發(fā)的時候你可以看到訪問的URL的層次,對你調試代碼還是很有幫助的。

以上的內容就是定義路由的全部內容。都是非常重要的知識,希望你能好好掌握,對于路由的嵌套請看之前的文章。如果有疑問請給我留言或者訪問官網(wǎng)看原教程。
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。绻阌X得博文對你有點用,請在github項目上給我點個star吧。您的肯定對我來說是最大的動力??!

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號