Ember数据父/子模型和json

时间:2013-09-16 18:51:57

标签: ember.js ember-data

我想为父母和孩子之间的关系以及理想的json结构以及路线和控制器的基本示例一劳永逸地记录(并保留永久记录!)。

当我(希望)得到答案和评论时,我会更新问题以反映最佳实践。

所以,我有我的余烬模型:

App.Customer  = DS.Model.extend({
    name: DS.attr('string' ),
    orders: DS.hasMany("order")
});

App.Order  = DS.Model.extend({
    carrier: DS.attr('string' ),
    customer: DS.belongsTo("customer")
    orderlines: DS.hasMany("orderline")

});

App.Orderline  = DS.Model.extend({
    order: DS.belongsTo("order"),
    item: DS.belongsTo("item"),
    price: DS.attr('number'),
    qty: DS.attr('number'),
});

App.Item  = DS.Model.extend({
    name: DS.attr('string'),
    orderlines: DS.hasMany("orderline")
});

问题1:这些模型定义是否正确?

我可以采用多种方法来查看这些数据:

  • 客户标签|订单标签|订单行标签
  • 客户页面 - >订单页面 - >订单行页面
  • Treeview
  • 任何人都可以建议任何其他可以显示此分层数据的JS小部件吗?

问题2:

每个路由器/控制器需要哪些?

我有选项2)工作到显示客户,但当我点击客户的订单链接时,我收到所有订单。可能是我的json错了..或者更有可能我不知道如何显示所选客户的所有订单。或者两者:(

我目前有:

{"customers":[
  {"name":"foobar inc","id":"0x181","orders":["0x386","0x3a4"]},
  {"name":"barfoo ltd","id":"0x182","orders":["0x3de","0x3fd"]} ],   
 "orders":[
   {"carrier":"Standard Mail","id":"0x386","customer_id":"0x181"},
   {"carrier":"FlyByNight Courier","id":"0x3a4","customer_id":"0x181"},
   {"carrier":"Standard Mail","id":"0x3de","customer_id":"0x182"},
   {"carrier":"FlyByNight Courier","id":"0x3fd","customer_id":"0x182"} ]}

问题3:这是正确的吗? (我可以让json以任何格式出现,因此最好创建最适合ember-data的json结构)。

问题4:此时我是否应该包含相关数据(所有客户,所有订单,所有订单)?或者最好不要包含子数据,但是从服务器上获取这些数据?

我现在就把它留下来 - 希望我能尽快开始理解嵌套数据!感谢。

1 个答案:

答案 0 :(得分:2)

问题1 这些模型定义对我来说很好。

问题2 您可能希望最终混合使用您的选项#1和#2。选项卡可让您查看每个模型的完整列表,但能够在/customers页面上按层次结构向下钻取。您需要的确切路线取决于您希望在应用中提供的确切网址,这些网址与您要显示的屏幕/视图相对应。

假设你想要这些网址/屏幕

/customers - 所有客户的列表

/customers/1 - 有关客户#1的详细信息

/customers/1/orders - 客户#1的所有订单

/customers/1/orders/1 - 订单#1的详细信息(包括OrderLine s)

然后您的路线将是:

App.Router.map(function() {
    this.resource('customers');
    this.resource('customer', { path: '/customers/:customer_id' }, function(){
        this.resource('orders');
        this.resource('order', { path: '/orders/:order_id'});
    });
});

问题3 是的,JSON看起来是正确的。

问题4 这取决于您的应用的需求。您可能不希望在单个请求中包含整个数据树(Customers - > Orders - > OrderLines - > Items)。您可能希望在用户离开树时逐步加载内容。

例如,您首先要加载客户列表,然后当用户点击客户时,您需要触发请求以获取该客户的所有订单。等等,在树下。

这是一个显示一般概念的JSBin:http://jsbin.com/ucanam/1074/edit

请注意,hasMany关系是使用{async:true}定义的。这允许按需查找它们,而不是使用父模型加载。

如果您切换到RESTAdapter,当它尝试加载客户的订单列表时,它会发出如下请求:

/orders?ids[]=0x3de&ids[]=0x3fd

[更新]:回应评论。

因此,对于您请求的网址结构:> >客户列表> - >客户详细信息> - >订单清单> - >订单详情> - >订单行列表> - >订单行详细信息

你与JSBin非常接近。绊倒你的是模板嵌套的工作方式。

'order'模板(如果存在)将针对符合/orders/xxx/orders/xxx/*的所有路线呈现。如果路线的其他部分(例如/orderlines)会将这些模板渲染到'order'模板中。但是,由于您的'order'模板没有{{outlet}},因此'orderlines'模板无需渲染。

这是一个稍微修改过的JSBin:http://jsbin.com/iKIsisO/3/edit

唯一的变化是在{{outlet}}模板的底部添加了'order'

现在,在主要订单明细内部下方呈现orderlines可能不是您想要的。您最有可能希望订单行替换其他订单信息。在这种情况下,您可以将'order'模板重命名为'order/index'。 (您也可以从OrderRoute删除needsOrderController

另一个JSBin,模板重命名为:http://jsbin.com/iDiMOCO/1/edit

那么,这里发生了什么?

Order模型为例,当您访问/orders路由以及适用于该集合的任何其他路由(/orders/new/orders/some_custom_batch_thing)时,如果主'orders'模板存在,则呈现该主模板,然后将子路径模板呈现为'orders'。如果'orders'模板不存在,则子路径模板将呈现到链中的{{outlet}}/orders路由是一种特殊情况,因为它的子模板被隐式假设为orders/index。同样,对于/orders/xxx以及适用于单个Order的任何其他路由,首先呈现'order'模板(如果存在),然后将子路径模板呈现为'order',或最直接的父{{outlet}}。另外,使用/orders/xxx 'order/index'模板是隐式子路径模板。

  • /orders :: 'orders' - > 'orders/index'
  • /orders/new :: 'orders' - > 'orders/new'
  • /order/xxx :: 'order' - > 'order/index'
  • /orders/xxx/edit :: 'order' - > 'order/edit'

因此,'orders''order'模板实际上类似于每个模型布局模板,可用于以一致的方式装饰子路径。

最终的JSBin,在模板中呈现模板名称,并添加一些额外的模板作为“模型布局”:http://jsbin.com/iKIsisO/2/edit

我希望一切都有道理。