Ember.js - CRUD 场景 - 从路由中指定视图 [英] Ember.js - CRUD scenarios - Specifying View from within a Route

查看:19
本文介绍了Ember.js - CRUD 场景 - 从路由中指定视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前问过一个问题,我想将驻留在控制器中的集合绑定到列表场景视图,但是,我添加了detailsedit 我的结构的模板和视图产生了几个额外的子路线:

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

在我的 details 场景中,我首先开始调用 connectOutlets 如下

In my details scenarios I first started calling the connectOutlets as follows

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

这会改变浏览器导航栏中的路线,但它会加载相同的视图,然后我将 .connectOutlet 更改为 contact 而不是 联系以下人员

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

[...]
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') 中使用了相同的名称.所以我所做的不可能是对的.我不想为每个场景创建控制器.我敢肯定这不是它的做法.

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). Also when I navigate to /#/contacts/2/edit it loads the details view since I'm using the same name in .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.

我也尝试设置视图(在我的例子中是 App.EditContactView)而不是 connectOutlets 中的资源名称,但我收到一个错误,说我可以通过一个名称或一个视图类,但不是两者",但我没有通过 viewClass 而是作为 connectOutlet 的参数传递.

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.

我还尝试将视图或我的视图实例设置为路由本身,我要么破坏 JavaScript一个方法 CharAt".

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

再说一次,我有点迷失了.我在 SO 和其他地方看到了其他问题,但我发现的问题要么使用 ember-routermanager by Gordon Hempton(这看起来不错,但我现在只对使用内置感兴趣),Ember.StateManager 或不使用状态/路由全部.文档尚未对这些内容进行过多解释.

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. Documentation isn't explaining too much about these things yet.

问题:使用 Ember.Router 处理所有 CRUD 场景的理想方法是什么?我希望我的 contactsController 能够列出所有联系人、找到一个、编辑一个、添加一个和删除一个联系人.现在我有一个带有 findAllcontactsController 和一个带有 findeditcontactController, remove, add 因为命名问题.

Question: What would be the ideal approach to deal with all CRUD scenarios with Ember.Router? I want my contactsController to be able to list all, find one, edit one, add one and delete one contact. Right now I have one contactsController with findAll and one contactController with find, edit, remove, add because of naming problems.

我目前没有使用 ember-data,所以我会对没有引用 ember-data 的例子更感兴趣(我现在正在做没有任何插件的婴儿步骤).

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

这是我的路由器的当前版本:

Here's the current version of my router:

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>

注意:如果有什么不清楚的,请在评论部分提问,我可以编辑更多细节

Note: If there's anything unclear, please ask in the comment section and I can edit this with more details

编辑:我已将此项目添加到 GitHub 即使它离我想作为学习样本公开的内容相去甚远.目标是在此基础上取得进展并在不久的将来创建一个 CRUD 模板.目前使用 MS Web API,但可能很快会添加 Rails 版本.

Edit: I've added this project to GitHub even tho it's nowhere near what I'd like to expose as a learning sample. The goal is to progress on top of this and create a CRUD template in a near future. Currently using MS Web API, but might add a Rails version soon.

推荐答案

这里发生了一些事情,我会尝试回答它们,但如果我错过了什么,请随时发表评论.你似乎在重新发明 Ember 已经为你做的很多事情.

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.

首先,如果您想将视图传递给 connectOutlet 方法,您需要传入一个散列作为唯一的参数.

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.

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

其次,拥有两个联系人控制器并不令人讨厌,事实上我会推荐它.从 ObjectController 继承的单一 ContactController 和从 ArrayController 继承的 ContactsController,这意味着您可以轻松利用内置的内容代理.

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.

第三,如果您将 findfindAll 类方法添加到您的模型中,您将更轻松.

Thirdly, if you add find and findAll class methods to your models you will make life much easier for yourself.

  • 您不需要定义已定义的序列化/反序列化方法,默认情况下,Ember 将查找具有从路由推导出的名称的模型,因此 :contact_id 将自动查找 App.Contact.find(:contact_id).

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

您还可以将索引 connectOutlets 更改为:router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())

You will also be able to change your index connectOutlets to: router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())

另外一个提示,目前您的详细信息和编辑路线几乎完全相同.我会创建一个名为 company 的路由,然后在其中创建子详细信息并编辑视图.

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.

这篇关于Ember.js - CRUD 场景 - 从路由中指定视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆