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

时间:2012-07-07 18:15:13

标签: javascript ember.js url-routing ember-old-router

我之前曾问过一个问题,我想bind a collection residing in the controller to the list scenario view,但是,我已将详细信息编辑模板和视图添加到我的结构中产生一些额外的子路线:

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更改为 联系人而不是联系人< / em> 到以下

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

因此,我不得不创建一个新的控制器,因为Ember找不到名为contactController的控制器,所以我最终得到了contactControllercontactsController,我认为我打破MVC模式这样做,以及创建一个额外的类来维护同步的可能问题(编辑联系人时我必须手动与contactsController中的集合同步)。此外,当我导航到/#/contacts/2/edit时,它会加载详细信息视图,因为我在.connectOutlet('contact')中使用了相同的名称。所以我正在做的事情是不对的。我不想为每个场景创建控制器。我确定这不是它的完成方式。

我还尝试设置视图(在我的情况下为App.EditContactView)而不是connectOutlets中的资源名称,但我收到错误消息,说我可以传递“名称或viewClass但是不是两个“但我没有通过viewClass而是作为connectOutlet的论据。

我还尝试将视图或视图实例设置为路径本身,我会破坏我的JavaScript或在某些情况下我会收到错误消息“ App.EditContactView没有一个方法CharAt “。

然后,我有点失落。我在SO和其他地方看到过其他问题,但我发现的那些问题是使用Gordon Hempton的ember-routermanager(看起来不错,但我现在只对使用内置函数感兴趣),{{ 1}}或者根本不使用状态/路由。文档并没有解释太多关于这些事情。

问题:使用Ember.StateManager处理所有CRUD方案的理想方法是什么? 我希望我的Ember.Router能够列出所有内容,找到一个,编辑一个,添加一个并删除一个联系人。现在我有一个contactsControllercontactsController和一个findAllcontactControllerfindeditremove因为命名问题。

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

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

JS

add

相关模板

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();

注意:如果有任何不清楚的地方,请在评论部分询问,我可以使用更多详细信息进行编辑

编辑:我已将此项目添加到GitHub,即使它远不是我想要作为学习样本公开的内容。我们的目标是在此基础上进步,并在不久的将来创建一个CRUD模板。目前正在使用MS Web API,但很快就会添加Rails版本。

1 个答案:

答案 0 :(得分:9)

这里有一些事情,我会尝试回答它们,但如果我错过任何事情,请随时发表评论。你似乎正在重塑Ember为你做的很多东西。

首先,如果要将视图传递给connectOutlet方法,则需要将哈希作为唯一参数传递。

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

其次,有两个接触控制器不是不赞成的,事实上我推荐它。从[{1}}继承的单数ContactController和从ObjectController继承的ContactsController,这意味着您可以轻松利用内置的代理内容。

第三,如果您将ArrayControllerfind类方法添加到模型中,您将使自己的生活更轻松。

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

  • 您还可以将索引connectOutlets更改为:findAll

还有一个提示,目前您的详细信息和编辑路线几乎完全相同。我将创建一个名为router.get('applicationController').connectOutlet('contacts', App.Contact.findAll())的单一路线,然后制作子详细信息并编辑其中的视图。