[英]Ember.js - CRUD scenarios - Specifying View from within a Route
I've asked a question previously in which I wanted to bind a collection residing in the controller to the list scenario view , however, I've added details and edit templates and views to my structure producing a couple of extra sub-routes: 我之前问了一个问题,我想将控制器中的一个集合绑定到列表场景视图 ,但是,我已经添加了详细信息并编辑了模板和视图到我的结构中,产生了一些额外的子路径:
root.contacts.details -> /contacts/:contact_id
root.contacts.edit -> /contacts/:contact_id/edit
In my details
scenarios I first started calling the connectOutlets
as follows 在我的
details
场景中,我首先开始调用connectOutlets
,如下所示
[...]
connectOutlets: function (router, contact) {
router.get('contactController').set('contact', contact);
router.get('applicationController').connectOutlet('contacts');
},[...]
This would change the route in the browser navigation bar, but it would load the same view, then I changed the .connectOutlet
to contact instead of contacts to the following 这会改变浏览器导航栏中的路线,但它会加载相同的视图,然后我
.connectOutlet
改为联系而不是联系人
[...]
connectOutlets: function (router, contact) {
router.get('contactController').set('contact', contact);
router.get('applicationController').connectOutlet('contact');
},[...]
Because of this, I had to create a new controller as Ember couldn't find a controller named contactController
, so I ended up with a contactController
and a contactsController
and I think I'm breaking the MVC pattern doing this, as well as creating an extra class to maintain, possible problems with syncronization (when editing a contact I'd have to manually sync with the collection in the contactsController
). 因此,我不得不创建一个新的控制器,因为Ember找不到名为
contactController
的控制器,所以我最终得到了一个contactController
和一个contactsController
,我想我打破了MVC模式这样做,以及创建一个额外的类维护,同步的可能问题(编辑联系人时我必须手动与contactsController
的集合同步)。 Also when I navigate to /#/contacts/2/edit
it loads the details view since I'm using the same name in .connectOutlet('contact')
. 此外,当我导航到
/#/contacts/2/edit
它会加载详细信息视图,因为我在.connectOutlet('contact')
使用相同的名称。 So what I'm doing can't be right. 所以我正在做的事情是不对的。 I don't want to create controller per scenario.
我不想为每个场景创建控制器。 I'm sure this is not how it's done.
我确定这不是它的完成方式。
I also tried setting the view (in my case App.EditContactView
) instead of the resource name in the connectOutlets
but I got an error saying I can pass " a name or a viewClass but not both " but I was not passing through viewClass
and rather as an argument of connectOutlet
. 我也试着设置(在我的观点
App.EditContactView
的,而不是资源名称) connectOutlets
但我得到一个错误,说我可以通过“ 一个名称或viewClass类但不能同时 ”,但我并没有经过viewClass
和相当作为connectOutlet
的参数。
I have also tried to set a view or an instance of my view to the route itself and I would either break my JavaScript or in some cases I'd get an error saying that " App.EditContactView does not have a method CharAt ". 我还尝试将视图或视图实例设置为路径本身,我会破坏我的JavaScript或在某些情况下我会收到一条错误,说“ App.EditContactView没有方法CharAt ”。
Then again, I got a little lost. 然后,我有点失落。 I have seen other questions at SO and else where but the ones I've found were either using
ember-routermanager
by Gordon Hempton (which seems good, but I'm interested in using built-in only right now), Ember.StateManager
or not using state/route at all. 我在SO和其他地方看到了其他问题但是我发现的那些问题要么是使用Gordon Hempton的
ember-routermanager
routermanager(看起来不错,但我现在只对内置使用感兴趣), Ember.StateManager
或者根本不使用州/路线。 Documentation isn't explaining too much about these things yet. 文档并没有解释太多关于这些事情。
Question : What would be the ideal approach to deal with all CRUD scenarios with Ember.Router
? 问题 :使用
Ember.Router
处理所有CRUD场景的理想方法是什么? I want my contactsController
to be able to list all, find one, edit one, add one and delete one contact. 我希望我的
contactsController
能够列出所有,找到一个,编辑一个,添加一个并删除一个联系人。 Right now I have one contactsController
with findAll
and one contactController
with find
, edit
, remove
, add
because of naming problems. 现在我有一个带有
findAll
contactsController
和一个带有find
, edit
, remove
, add
contactController
,因为命名问题。
I am currently not using ember-data so I would be more interested in examples without references to ember-data (I am doing the baby steps without any plug-in for now). 我目前没有使用余烬数据,所以我对没有参考ember-data的例子更感兴趣(我现在正在做没有任何插件的婴儿步骤)。
Here's the current version of my router: 这是我的路由器的当前版本:
JS 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();
Relevant templates 相关模板
<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>
Note : If there's anything unclear, please ask in the comment section and I can edit this with more details 注意 :如果有任何不清楚的地方,请在评论部分询问,我可以使用更多详细信息进行编辑
Edit : I've added this project to GitHub even tho it's nowhere near what I'd like to expose as a learning sample. 编辑 :我已经将这个项目添加到GitHub,即使它远不是我想要作为学习样本公开的内容。 The goal is to progress on top of this and create a CRUD template in a near future.
我们的目标是在此基础上进步,并在不久的将来创建一个CRUD模板。 Currently using MS Web API, but might add a Rails version soon.
目前正在使用MS Web API,但很快就会添加Rails版本。
There's a few things going on here, I'll try and answer them, but if I miss anything feel free to leave a comment. 这里有一些事情,我会尝试回答它们,但如果我错过任何事情,请随时发表评论。 You seem to be reinventing a lot of stuff Ember already does for you.
你似乎正在重塑Ember为你做的很多东西。
Firstly, if you want to pass a view to the connectOutlet
method you need to pass in a hash as the one and only argument. 首先,如果要将视图传递给
connectOutlet
方法,则需要将哈希作为唯一参数传递。
router.get('applicationController').connectOutlet({
viewClass: App.EditContactView,
controller: router.get('contactsController'),
context: context
})
Secondly, having two contact controllers is not frowned upon, in fact I'd recommend it. 其次,有两个接触控制器不是不赞成,事实上我推荐它。 A singular
ContactController
that inherits from ObjectController
and a ContactsController
that inherits from ArrayController
, this means you can easily take advantage of the content proxies built in. 一个继承自
ObjectController
单一ContactController
和一个继承自ArrayController
的ContactsController
,这意味着您可以轻松利用内置的代理内容。
Thirdly, if you add find
and findAll
class methods to your models you will make life much easier for yourself. 第三,如果您将
find
和findAll
类方法添加到模型中,您将使自己的生活更轻松。
You won't need to define the serialize/deserialize methods you have defined, by default Ember will look for a model with the name deduced from the route so :contact_id will automatically look for App.Contact.find(:contact_id). 您不需要定义已定义的序列化/反序列化方法,默认情况下,Ember将查找具有从路由推断出的名称的模型,因此:contact_id将自动查找App.Contact.find(:contact_id)。
You will also be able to change your index connectOutlets to: router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())
您还可以将索引connectOutlets更改为:
router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())
One more tip, currently your details and edit routes are almost completely identical. 还有一个提示,目前您的详细信息和编辑路线几乎完全相同。 I would create a single route called
company
and then make child details and edit views inside of it. 我会创建一个名为
company
路由,然后创建子详细信息并编辑其中的视图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.