简体   繁体   English

Ember.js - CRUD场景 - 从路径中指定视图

[英]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和一个带有findeditremoveadd 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和一个继承自ArrayControllerContactsController ,这意味着您可以轻松利用内置的代理内容。

Thirdly, if you add find and findAll class methods to your models you will make life much easier for yourself. 第三,如果您将findfindAll类方法添加到模型中,您将使自己的生活更轻松。

  • 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM