[英]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.