2012-07-07 14 views
7

我問了一個問題以前,我想bind a collection residing in the controller to the list scenario view,但是,我已經添加細節編輯模板和意見,我的生產結構一對額外的子路線:Ember.js - CRUD場景 - 從路徑中指定查看

root.contacts.details -> /contacts/:contact_id
root.contacts.edit -> /contacts/:contact_id/edit

在我details情景我第一次開始調用connectOutlets如下

[...] 
connectOutlets: function (router, contact) { 
    router.get('contactController').set('contact', contact); 
    router.get('applicationController').connectOutlet('contacts'); 
},[...] 

這會改變在瀏覽器導航欄的路線,但它會加載相同的視圖,然後我改變了.connectOutlet接觸代替觸點以下

[...] 
connectOutlets: function (router, contact) { 
    router.get('contactController').set('contact', contact); 
    router.get('applicationController').connectOutlet('contact'); 
},[...] 

正因爲如此,我不得不創建一個新的控制器,因爲Ember無法找到名爲contactController的控制器,所以我最終得到了contactControllercontactsController,我認爲我打破了這樣做的MVC模式,以及創建一個額外的類來維護,同步可能出現的問題(編輯聯繫人時,我必須手動與contactsController中的集合同步)。另外,當我導航到/#/contacts/2/edit時,它會加載詳細信息視圖,因爲我在.connectOutlet('contact')中使用了相同的名稱。所以我正在做的事情是不對的。我不想爲每個場景創建控制器。我相信這不是如何完成的。

我也試過在connectOutlets設置視圖(在我的情況App.EditContactView),而不是資源的名字,但我得到了一個錯誤,說我可以通過「名稱或viewClass類,但不能同時」但我不及格通過viewClass,而不是作爲connectOutlet的論點。

我也試圖設置一個視圖或我的視圖的實例路線本身,我會打破我的JavaScript或在某些情況下,我會得到一個錯誤,說「App.EditContactView沒有方法CharAt「。

然後我又有點迷路了。我在SO上看到過其他問題,除此之外,我發現使用Gordon Hempton的ember-routermanager(這看起來不錯,但我只對現在使用內置感興趣),Ember.StateManager或者沒有使用state /在所有路線。文檔沒有太多解釋這些事情。

問題:用Ember.Router來處理所有CRUD場景的理想方法是什麼? 我希望我的contactsController能夠列出全部,找到一個,編輯一個,添加一個並刪除一個聯繫人。現在我有一個contactsControllerfindAll和一個contactControllerfind,edit,remove,add由於命名問題。

我目前沒有使用燼數據,所以我會更感興趣的例子沒有引用燼數據(我現在做沒有任何插件的嬰兒步驟)。

這裏是我的路由器的當前版本:

JS

App.Router = Ember.Router.extend({ 
    enableLogging: true, 
    location: 'hash', 

    root: Ember.Route.extend({ 
     // EVENTS 
     gotoHome: Ember.Route.transitionTo('home'), 
     gotoContacts: Ember.Route.transitionTo('contacts.index'), 

     // STATES 
     home: Ember.Route.extend({ 
      route: '/', 
      connectOutlets: function (router, context) { 
       router.get('applicationController').connectOutlet('home'); 
      } 
     }), 
     contacts: Ember.Route.extend({ 
      route: '/contacts', 
      index: Ember.Route.extend({ 
       route: '/', 
       contactDetails: function (router, context) { 
        var contact = context.context; 
        router.transitionTo('details', contact); 
       }, 
       contactEdit: function (router, context) { 
        var contact = context.context; 
        router.transitionTo('edit', contact); 
       }, 
       connectOutlets: function (router, context) { 
        router.get('contactsController').findAll(); 
        router.get('applicationController').connectOutlet('contacts', router.get('contactsController').content); 
       } 
      }), 
      details: Ember.Route.extend({ 
       route: '/:contact_id', 
       view: App.ContactView, 
       connectOutlets: function (router, contact) { 
        router.get('contactController').set('contact', contact); 
        router.get('applicationController').connectOutlet('contact'); 
       }, 
       serialize: function (router, contact) { 
        return { "contact_id": contact.get('id') } 
       }, 
       deserialize: function (router, params) { 
        return router.get('contactController').find(params["contact_id"]); 
       } 
      }), 
      edit: Ember.Route.extend({ 
       route: '/:contact_id/edit', 
       viewClass: App.EditContactView, 
       connectOutlets: function (router, contact) { 
        router.get('contactController').set('contact', contact); 
        router.get('applicationController').connectOutlet('contact'); 
       }, 
       serialize: function (router, contact) { 
        return { "contact_id": contact.get('id') } 
       }, 
       deserialize: function (router, params) { 
        return router.get('contactController').find(params["contact_id"]); 
       } 
      }) 
     }) 
    }) 
}); 
App.initialize(); 

相關模板

<script type="text/x-handlebars" data-template-name="contact-details"> 
    {{#if controller.isLoaded}} 
     <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="210" height="240" /><br /> 
     <strong>{{contact.fullName}}</strong><br /> 
     <strong>{{contact.alias}}</strong> 
    {{else}} 
     <img src="images/l.gif" alt="" /> Loading... 
    {{/if}} 
</script> 

<script type="text/x-handlebars" data-template-name="contact-edit"> 
    <strong>Edit contact</strong><br /> 
    First Name: <input type="text" id="txtFirstName" {{bindAttr value="contact.firstName"}}<br /> 
    Lasst Name: <input type="text" id="txtLastName" {{bindAttr value="contact.lastName"}}<br /> 
    Email: <input type="text" id="txtEmail" {{bindAttr value="contact.email"}}<br /> 
</script> 

<script type="text/x-handlebars" data-template-name="contact-table-row"> 
    <tr> 
     <td> 
      <img {{bindAttr src="contact.imageUrl" alt="contact.fullName" title="contact.fullName"}} width="50" height="50" /><br />{{contact.fullName}} 
     </td> 
     <td> 
      Twitter: {{#if contact.twitter}}<a {{bindAttr href="contact.twitter"}} target='_blank'>Follow on Twitter</a>{{else}}-{{/if}}<br /> 
     </td> 
     <td> 
      <a href="#" {{action contactDetails context="contact"}}>Details</a> | 
      <a href="#" {{action contactEdit context="contact"}}>Edit</a> 
     </td> 
    </tr> 
</script> 

注意:如果有什麼不清楚的地方,請諮詢中評論部分,我可以e DIT這更多的細節

編輯:我已經添加了這個項目GitHub即使壽它遠不及希望我揭露作爲一個學習的樣本。目標是在此基礎上取得進展,並在不久的將來創建一個CRUD模板。目前使用MS Web API,但很快可能會添加Rails版本。

+0

我得到一個404鏈接到Github頁面。最近這個變化了嗎? – mkelley33 2012-09-24 05:31:22

+1

是的..我改變了項目名稱。這裏是[新鏈接](https://github.com/MilkyWayJoe/hello-ember-router) – MilkyWayJoe 2012-09-24 13:16:28

+0

謝謝@MilkyWayJoe – mkelley33 2012-09-24 22:46:50

回答

9

這裏有幾件事情,我會盡力回答,但如果我錯過任何事情,請隨時發表評論。你似乎正在重塑Ember已經爲你做的很多東西。

首先,如果你想傳遞一個視圖到connectOutlet方法,你需要傳入一個散列作爲唯一的參數。

router.get('applicationController').connectOutlet({ 
    viewClass: App.EditContactView, 
    controller: router.get('contactsController'), 
    context: context 
}) 

其次,有兩個接觸控制器不皺眉,實際上我會推薦它。單數ContactControllerObjectControllerContactsControllerArrayController繼承繼承,這意味着你可以輕鬆地建在內容代理的優勢。

第三,如果添加findfindAll類的方法,以你的模型將使生活對自己來說更容易。

  • 你不會需要定義你所定義的序列化/反序列化方法,默認情況下灰燼將尋找從路線,以便推斷名稱型號:CONTACT_ID會自動尋找App.Contact.find (:CONTACT_ID)。

  • 你也可以改變你的指數connectOutlets到:router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())

一個提示,目前您的詳細資料和編輯路線幾乎完全一致。我會創建一個名爲company的路線,然後在其中創建子細節並編輯視圖。

+0

感謝您的回答,我會一點一滴地對此進行討論,但在我嘗試之前,我想知道更多關於控制器的信息,您如何去同步數據?假設你在控制器中有一個從ObjectController繼承的創建方法,你會手動將一個由ObjectController實例創建的記錄拷貝到ArrayController集合中嗎?也許我太嚴格了,但我不認爲我喜歡爲同一資源類型設置多個控制器,這是Ember的慣例嗎?(我有一個不同的應用程序,使用StateManager和這個資源的單個控制器) – MilkyWayJoe 2012-07-08 12:29:33

+0

如果我在'connectOutlet'中用這段代碼調用我的'edit'路徑,它會拋出'Uncaught Error:斷言失敗:您必須提供一個名稱或視圖類connectOutlets,但不是兩個' – MilkyWayJoe 2012-07-08 12:34:58

+0

我已經'viewClassName:App.EditContactView'更改爲'viewClass:App.EditContactView'。我不再收到以前的錯誤消息,但我的路線和視圖將不會加載。網址保持不變,視圖保持不變,只是現在沒有數據。 – MilkyWayJoe 2012-07-08 12:51:26