2013-04-26 83 views
1

我正在分别加载两组数据,但我希望它们是相关的。请允许我解释一下。在Ember中关联两组JSON数据

首先,我没有使用Ember-data,而是使用简单的$.ajax包装,如this post from one of the Discourse team中所述。

我有一个频道和节目的概念。

频道JSON:

[{ 
    "ID":94, 
    "Name":"BBC1" 
}, 
{ 
    "ID":105, 
    "Name":"BBC2" 
}] 

我必须收集从这个JSON的ID,以便能够然后请求程序这些通道。因此,从端点看起来有点像这样的程序的响应:

程序JSON:

{ 
    "Channels": [ 
     { 
      "Listings": [ 
       { 
        "Id": "wcy2g", 
        "Genres": "Education", 
        "S": "2013-04-26T10:45", 
        "E": "2013-04-26T11:15", 
        "T": "Crime Scene Rescue" 
       } 
      ] 
     }, 
     { 
      "Listings": [ 
       { 
        "Id": "wcwbs", 
        "Genres": "Current affairs,News", 
        "S": "2013-04-26T11:00", 
        "E": "2013-04-26T12:00", 
        "PID": "nyg", 
        "T": "Daily Politics" 
       } 
      ] 
     } 
    ] 
} 

enter image description here

每个Listings数组可以包含的项目X量和Channels对象数组与它们的请求顺序(来自Channels.json的ID)有关,因此在这种情况下,Channels[0]是BBC1,而Channels[1]是BBC2。

我想是要求这两个数据集作为一个JSON每个但后来不知怎的涉及他们的请求。所以拥有一个拥有x个程序模型的通道控制器。我还需要在两个不同的模板中渲染通道和程序

正在考虑我可以遍历channels.json并使用该项目的索引来查找programmes.json中的相关项目并以此方式创建关系。

不太确定如何使用Ember来实现这一点。

谢谢

回答

2

我做了一件非常相似的事情,并得到它在烬中工作。我会用你的物体勾画出我所做的。请注意,我是相当新的烬,所以一粒盐可能是必要的。

首先,你会希望有模型对象的“通道”,“通道”和“程序”。这将最终让你拥有控制器和路由器,这些都可以很好地匹配ember的命名约定。 ChannelsData将会有很多ChannelData对象,并且每个ChannelData都会有很多ProgrammeData对象。你如何得到这些人口?

在你ChannelsRoute类,你可以有一个模型()函数返回模型数据的这条路线。您的模型函数可以在ChannelsData上调用create()来创建实例,然后在ChannelsData上调用loadAll函数。 ChannelsData使用您喜欢的ajax风格实现loadAll()。最简单最简单的方法是让该函数执行两个Ajax调用并构建整个数据树。

然后,您将发现,如果你输入的路径喜欢#/渠道/ 105直接在浏览器中,你会如果你的ChannelRoute类尝试调用它的模型(陷入困境),例如。要解决这个问题,请在您的App对象上创建一个自己的简单对象库,如App.ChannelsStore = {},并且在创建每个Channel时,在ChannelsStore中(通过id)添加对它的引用。然后你的ChannelRoute.model函数可以从该商店查找它的模型。但是只有ChannelsRoute.model先完成!

如果用户输入#/ channels/105路由作为第一次进入您的应用程序,那么您的代码将通过ChannelsRoute.model()方法,并立即通过ChannelRoute.model()方法,可能在你的ajax完成之前。在这种情况下,您可以让ChannelRoute.model()方法创建一个临时通道(例如没有程序),并将其放入App.ChannelsStore中。然后,用于构建整个数据树的逻辑应该愿意检查ChannelsStore以查看具有给定ID的对象是否已经存在,如果是,则更新它。你最终的东西,如:

App.ChannelRoute = Ember.Route.extend({ 
    model: function(params) { 
    var channel = App.ChannelsStore[params.channel_id]; 
    // create stub version if not found 
    if (!channel) { 
     channel = App.ChannelData.create({ID: params.channel_id}); 
     App.ChannelsStore[params.channel_id] = channel; 
    } 
    return channel; 
    } 
}); 

(你可能最终同样构建ProgrammeStore,但是这只是更多的相同。)

的临时对象的更新实际上表明了一个非常酷的方面呃,这是你的用户界面可能会显示临时对象的值,但是当你的Ajax调用完成并且频道和程序全部加载 - 你的用户界面会正确更新。只要确保使用set()方法更新对象,并且您的UI模板很乐意使用部分数据。

+0

这是很棒的东西,谢谢。关于你在存储和路线上的观点,这将全部发生在一条路线上(这是一个交互式网格)。所以我可能会在setupController方法中将所有东西都挂钩。您将如何创建程序模型,并在获取两组JSON时将它们与每个通道相关联? – 2013-04-27 23:31:01

+0

“each”方法的某些版本会照顾你。例如,jQuery的每一个都允许你运行你的程序json,给出channel数组中每个元素的索引和值。这会让你得到你需要连接到你的频道的json。 – kevinw 2013-04-29 17:11:06