1

我想为自己一劳永逸地记录(并永久记录!)父母和孩子之间的关系以及理想的 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:这些模型定义是否正确?

我可以采取几种方法来查看这些数据:

  • 客户标签 | 订单标签 | 订单行选项卡
  • 客户页面 -> 订单页面 -> 订单行页面
  • 树视图
  • 任何人都可以建议任何其他可以显示此分层数据的 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:此时我是否应该包括相关数据(所有客户、所有订单、所有订单行)?或者最好不要包含子数据,而是从服务器按需获取这些数据?

我将暂时离开它 - 希望我能很快开始理解嵌套数据!谢谢。

4

1 回答 1

2

问题 1这些模型定义对我来说看起来不错。

问题 2您可能希望混合使用选项 #1 和 #2。选项卡可让您查看每个模型的完整列表,但还可以在/customers页面上进行分层钻取。您需要的确切路线取决于您希望在应用中可用的确切 URL,这些 URL 将与您要显示的屏幕/视图相对应。

假设您想要这些 URL/屏幕

/customers- 所有客户的名单

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

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

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

那么您的路线将是:

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这取决于您的应用程序的需求。可能您不想在单个请求中包含整个数据树(客户 -> 订单 -> 订单行 -> 项目)。当用户下树时,您可能希望逐步加载内容。

例如,您首先只想加载客户列表,然后当用户单击客户时,您会发出请求以获取该客户的所有订单。依此类推,下树。

这是一个展示总体思路的 JSBin:http: //jsbin.com/ucanam/1074/edit

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

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

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

[更新]:回应评论。

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

你和你的 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主模板,然后将子路径模板渲染到. 如果模板不存在,则子路径模板会立即呈现到链上。路由是一种特殊情况,因为它的子模板被隐式假设为. 类似地,使用适用于单个的任何其他路由,首先呈现模板(如果存在),然后将子路径模板呈现到或最直接的 parent中。还与'orders''orders''orders'{{outlet}}/ordersorders/index/orders/xxxOrder'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

我希望一切都说得通。

于 2013-09-17T06:00:59.723 回答