[英]Ember.js - CRUD scenarios - Specifying View from within a Route
我之前問了一個問題,我想將控制器中的一個集合綁定到列表場景視圖 ,但是,我已經添加了詳細信息並編輯了模板和視圖到我的結構中,產生了一些額外的子路徑:
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
的控制器,所以我最終得到了一個contactController
和一個contactsController
,我想我打破了MVC模式這樣做,以及創建一個額外的類維護,同步的可能問題(編輯聯系人時我必須手動與contactsController
的集合同步)。 此外,當我導航到/#/contacts/2/edit
它會加載詳細信息視圖,因為我在.connectOutlet('contact')
使用相同的名稱。 所以我正在做的事情是不對的。 我不想為每個場景創建控制器。 我確定這不是它的完成方式。
我也試着設置(在我的觀點App.EditContactView
的,而不是資源名稱) connectOutlets
但我得到一個錯誤,說我可以通過“ 一個名稱或viewClass類但不能同時 ”,但我並沒有經過viewClass
和相當作為connectOutlet
的參數。
我還嘗試將視圖或視圖實例設置為路徑本身,我會破壞我的JavaScript或在某些情況下我會收到一條錯誤,說“ App.EditContactView沒有方法CharAt ”。
然后,我有點失落。 我在SO和其他地方看到了其他問題但是我發現的那些問題要么是使用Gordon Hempton的ember-routermanager
routermanager(看起來不錯,但我現在只對內置使用感興趣), Ember.StateManager
或者根本不使用州/路線。 文檔並沒有解釋太多關於這些事情。
問題 :使用Ember.Router
處理所有CRUD場景的理想方法是什么? 我希望我的contactsController
能夠列出所有,找到一個,編輯一個,添加一個並刪除一個聯系人。 現在我有一個帶有findAll
contactsController
和一個帶有find
, edit
, remove
, add
contactController
,因為命名問題。
我目前沒有使用余燼數據,所以我對沒有參考ember-data的例子更感興趣(我現在正在做沒有任何插件的嬰兒步驟)。
這是我的路由器的當前版本:
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>
注意 :如果有任何不清楚的地方,請在評論部分詢問,我可以使用更多詳細信息進行編輯
編輯 :我已經將這個項目添加到GitHub,即使它遠不是我想要作為學習樣本公開的內容。 我們的目標是在此基礎上進步,並在不久的將來創建一個CRUD模板。 目前正在使用MS Web API,但很快就會添加Rails版本。
這里有一些事情,我會嘗試回答它們,但如果我錯過任何事情,請隨時發表評論。 你似乎正在重塑Ember為你做的很多東西。
首先,如果要將視圖傳遞給connectOutlet
方法,則需要將哈希作為唯一參數傳遞。
router.get('applicationController').connectOutlet({
viewClass: App.EditContactView,
controller: router.get('contactsController'),
context: context
})
其次,有兩個接觸控制器不是不贊成,事實上我推薦它。 一個繼承自ObjectController
單一ContactController
和一個繼承自ArrayController
的ContactsController
,這意味着您可以輕松利用內置的代理內容。
第三,如果您將find
和findAll
類方法添加到模型中,您將使自己的生活更輕松。
您不需要定義已定義的序列化/反序列化方法,默認情況下,Ember將查找具有從路由推斷出的名稱的模型,因此:contact_id將自動查找App.Contact.find(:contact_id)。
您還可以將索引connectOutlets更改為: router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())
還有一個提示,目前您的詳細信息和編輯路線幾乎完全相同。 我會創建一個名為company
路由,然后創建子詳細信息並編輯其中的視圖。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.