簡體   English   中英

了解Ember.js中的路由

[英]Understand routing in Ember.js

我真的很難理解Ember中的路由概念,但比它看起來更復雜。 來自doc。 每當有不同的URL或路徑時,你可以看到你有不同的路由,如果你在同一個url中有不同的路徑,你只需要創建一個嵌套模板。 但是當你在一個網址中有3條不同的路徑時呢?

和this.resource和this.route的區別是什么?

由於實例總是比純理論更好,這里是我的應用程序。 在索引或'/'中我應該呈現“列表模板”,“新模板”,當用戶點擊列表鏈接時,“注釋模板”將呈現為“新模板”。

我的路由器:

Notes.Router.map(function () {
  this.resource('index', { path: '/' }, function (){
    this.resource('list', {path: ':note_title'});
    this.resource('new', {path: '/'});
this.resource('note', { path: ':note_id' });
});
});

我的模板:

<script type="text/x-handlebars" data-template-name="index"> 
  <div class="wrap">
    <div class="bar">
    {{input type="text" class="search" placeholder="Where is my bookmark??" value=search action="query"}}

      <div class="bar-buttons">
        <button {{action "addNote"}}> NEW </button>
      </div>
    </div>
    {{outlet}}
  </div> 
</script>

<script type="text/x-handlebars" data-template-name="list">
<aside>
  <h4 class="all-notes">All Notes {{length}}</h4>
    {{#each item in model}}
      <li>
       {{#link-to 'note' item}} {{item.title}} {{/link-to}}
      </li>
    {{/each}}
</aside>
</script>

<script type="text/x-handlebars" data-template-name="new"> 
   <section>
    <div class="note">
      {{input type="text" placeholder="Title" value=newTitle action="createNote"}}
      <div class="error" id="error" style="display:none"> Fill in the Title! </div>

      {{input type="text" placeholder="What you need to remember?" value=newBody action="createNote"}}
      {{input type="text" placeholder="Url:" value=newUrl action="createNote"}}
    </div>
   </section>
 </script>

  <script type="text/x-handlebars" data-template-name="note"> 
    <section>
        <div class="note">
            {{#if isEditing}}
              <h2 class="note-title input-title"> {{edit-input-note value=title focus-out="modified" insert-newline="modified"}} </h2>
              <p class="input-body"> {{edit-area-note value=body focus-out="modified" insert-newline="modified"}} </p>
              {{edit-input-note value=url focus-out="modified" insert-newline="modified"}}
            {{else}}
              <h2 {{action "editNote" on="doubleClick"}} class="note-title" > {{title}} </h2>
              <button {{action "removeNote"}} class="delete"> Delete </button>
              <p {{action "editNote" on="doubleClick"}}> {{body}} </p>
              {{input type="text" placeholder="URL:" class="input"  value=url }}
            {{/if}}
        </div>
      </section>
  </script>

或者在這里Js Bin: http//jsbin.com/oWeLuvo/1/edit?html ,js, output

如果需要我的控制器或模型,我也會添加該代碼。 提前致謝

你的例子似乎有效。

你只是想念依賴。 你沒有包括Handlebars和Ember.data

如果您已經檢查過您的javascript控制台,那么您已經看到了錯誤。

工作示例: http//jsbin.com/oWeLuvo/2/

在Ember,資源和路線都是路線。 它們有兩個名稱,以便Ember區分資源和路徑。 老實說要記住,它們都是路線,為了保持理智,你可以將它們分別稱為“資源路線”和“路線”。 資源可以嵌套並具有嵌套在其中的子資源或路由。 另一方面,路由不能嵌套任何東西。

如果您尚未使用,請安裝 Ember Inspector 它是一個Chrome擴展程序,可以幫助您安裝路由器,控制器,模板,數據以及安裝在Chrome Web瀏覽器中的其他很多其他東西。 我聽說Ember Inspector的最后一個也可以在FireFox Dev Tools中找到。 https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi?hl=en

因此,如果有資源,您可以嵌套資源和路由。 嵌套資源將保留其名稱空間,路由將附加到嵌套名稱空間。 請記住,您不能在路線中嵌套任何東西。

 App.Router.map(function() {
   //creating a resource
   this.resource('foo', {path: 'somePathYouPut'}, function() {
     //nesting stuff inside of the resource above

     //could open another nest level here in bar if you want
     this.resource('bar');

     //can not nest in route. Sad face. Sorry
     this.route('zoo');
   });
 });

由於您無法將任何內容嵌套到路徑中,因此index模板中的{{outlet}}沒有要查找的子項,默認情況下會呈現為{{outlet}}。 我相信這就是你認為會發生的事情。

 <script type="text/x-handlebars" data-template-name="index"> 
   <div class="wrap">
     <div class="bar">
       {{input type="text" class="search" 
         placeholder="Where is my bookmark??" value=search action="query"}}

     <div class="bar-buttons">
     <button {{action "addNote"}}> NEW </button>
    </div>
  </div>
  {{outlet}}
 </div> 
</script>

在您的代碼中,您將index稱為資源,它是一個路由。 由於索引是一個路由,記住你不能在一個路由中嵌套元素,你的代碼看起來應該更像這樣。 此外,您的resource “新”路/也可被移除。

 Notes.Router.map(function () {  
   //this is a route not a resource you had it as resource 
   //and tried to nest in your code
   this.route('index', { path: '/' });
   this.resource('list', {path: ':note_title'});
   this.resource('new');
   this.resource('note', { path: ':note_id' });
 });

您在每個嵌套級別獲得一個index ,從應用程序級別的最高級別開始,但您不必在路由器中明確定義它們。 您在每個嵌套級別免費獲得的index路由默認情況下與其直接父級關聯,並默認情況下呈現到其父級“插座”。 您可以認為路由器看起來像這樣。

用於說明目的:

Notes.Router.map(function() {
  //think of this as your application level stuff that Ember just does!!
  //this is not written like this but to illustrate what is going on
  //you would get application template, ApplicationRoute, ApplicationController
  this.resource('application', function() {

    //this is an index that you get for free cause its nested
    //its that index template, IndexController, and IndexRoute you were using
    this.route('index', { path: '/' });

    this.resource('foo', {path: 'somePathYouPutHere' }, function() {
      //since you started another nested level surprise you get another `index`
      //but this one is `foo/index` template.
      this.route('index', {path: '/'});
      this.route('zoo');
    });
  });
});

上面誇大的路由器示例的第一部分,Ember會自動在幕后,它是你聽到的“魔法”的一部分。 它為自己設置一個應用程序環境做了兩件事,你得到了ApplicationRouteApplicationController和一個總是在幕后的application模板。 其次,它會生成該index並獲得IndexController ,IndexRoute和可以使用或忽略的index模板。 因此,如果您不執行任何其他操作,則無法在var App = Ember.Application.create();等文件中聲明和Ember App的其他代碼var App = Ember.Application.create(); 並打開Ember Inspector並查看您將看到上述資產的路線。

現在,上面路由器中的資源foo就是你要做的資源的一個例子,當你看到你在那里得到一個index因為你開始嵌套了。 如上所述,您不必在每個嵌套級別定義索引, this.route('index', {path: '/'}); 從內部foo可以完全省略,Ember仍然會做同樣的事情。 最終將使用foo/index模板, FooIndexRouteFooIndexController以及預期的foo模板, FooRoute和FooController . You can think of the . You can think of the foo index as a place that says 'hey' before anything else gets rolled into my parent foo index as a place that says 'hey' before anything else gets rolled into my parent並且被渲染index as a place that says 'hey' before anything else gets rolled into my parent如果你願意我可以展示一些東西,使用我。

這也是一個很好的時機來突出在上面的例子中在像this.route('zoo')這樣的資源中嵌套路由時命名空間會發生什么。 路由zoo的命名空間現在將被附加到資源foo ,最終會得到foo/zoo模板, FooZooRouteFooZooController

如果你要將zoo更改為嵌套在foo資源this.resource('zoo');中的資源this.resource('zoo'); 命名空間將保留給動物園。 最終將使用'zoo'模板, ZooRouteZooController 保留名稱空間。 好的,足夠的一面跟蹤你的應用程序。

你說你想要/你的應用程序的url來呈現list template 為了實現這一點,您必須覆蓋Ember啟動時發生的默認行為。 您可以通過將{path: '/'}到路由器中的第一個資源或路由來覆蓋頂級/ 從您獲得的第一個index路由上方的虛假路由器代碼與應用程序關聯。 默認情況下,如果不執行任何操作,Ember會將該index模板推送到application模板中。 但是,如果您為應用程序點擊/ '的基本URL,則不希望將list模板推送到應用程序模板中。

Notes.Router.map(function() { 
  this.resource('list', {path: '/'});
  this.resource('new');
  this.resource('note', { path: ':note_id' });
});

通過像我上面那樣將代碼{path: '/'}到第一個資源,你現在告訴Ember'嘿'當我的app url到達/的基本URL時或者當你啟動時使用我的列表模板而不是你的默認index模板並將其呈現到應用程序模板中。 此外,由於當您的應用程序通過URL轉換到這些路徑時,其他資源不會嵌套,因此它們會在應用程序模板{{outlet}}中顯示出什么,並在那里替換它們自己。

你提到過在路由中定義一個“路徑”,它告訴Ember你想如何在url中表示該路由。 在上面的示例中,如果保留新資源,默認情況下,Ember將使用路由名稱作為路徑,url將為/new 您可以在新資源的路徑中放置任何名稱, this.resource(new, {path :'emberMakesMeKingOfWorld'}); 並且該名稱將在URL中表示為/emberMakesMeKingOfWorld並且該長項仍將與您的新路由相關聯。 您的用戶可能會對這個網址的含義感到困惑,但在您知道它與您的新路線綁定的情況之后。 它只是一個示例,但可能是使用描述性名稱的良好做法,以便您的用戶知道在您的應用程序中擊中網址的目的是什么。

覆蓋與應用程序關聯的默認index模板后。 我將您的代碼移動到應用程序模板中。 原因似乎是你希望那個帶有'newNote'動作的欄一直存在。 如果你想在你的應用程序中一直存在一些東西,比如導航欄,頁腳,我相信你可以想到更好的東西,把它放在應用程序模板中。

這是一個JSBIN,我調整了一些代碼

http://jsbin.com/oWeLuvo/8

我希望這有助於Happy Coding。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM