【问题标题】:Relating two sets of JSON data in Ember在 Ember 中关联两组 JSON 数据
【发布时间】:2013-04-26 12:47:47
【问题描述】:

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

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

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

频道 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"
                }
            ]
        }
    ]
}

每个 Listings 数组可以包含 x 个程序,Channels 数组中的对象与请求它们的顺序相关(通过 Channels.json 中的 ID),因此在这种情况下 Channels[0] 是BBC1 和Channels[1] 是 BBC2。

我希望将这两个数据集作为一个 JSON 请求分别请求,然后以某种方式将它们关联起来。因此,拥有一个具有 x 个程序模型的通道控制器。我还需要在两个不同的模板中渲染频道及其节目

当时我在想我可以遍历 channels.json 并使用项目的索引来查找 programmes.json 中的相关项目并以这种方式创建关系。

不太清楚如何使用 Ember 来实现这一点。

谢谢

【问题讨论】:

    标签: javascript ember.js


    【解决方案1】:

    我做了一些与此非常相似的事情,并让它在 ember 中工作。我会用你的对象勾勒出我做了什么。请注意,我对 ember 还很陌生,所以可能需要一点盐。

    首先,您需要有“Channels”、“Channel”和“Programme”的模型对象。这最终会让你为这些东西拥有控制器和路由器,与 ember 的命名约定很好地匹配。 ChannelsData 里面会有很多 ChannelData 对象,每个 ChannelData 都会有很多 ProgrammeData 对象。你如何得到这些填充?

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

    然后你会发现,如果你的 ChannelRoute 类试图调用它的 model(),你会遇到麻烦,例如,如果你直接在浏览器中输入像 #/channels/105 这样的路径。要解决这个问题,请在您的 App 对象上创建一个您自己的简单对象存储,例如 App.ChannelsStore = {},并在创建每个 Channel 时在您的 ChannelsStore 中放置对它的引用(按 id)。然后您的 ChannelRoute.model 函数可以从该商店中查找其模型。但前提是 ChannelsRoute.model 先完成!

    如果用户将 #/channels/105 路由作为第一个进入您的应用程序,那么您的代码将通过 ChannelsRoute.model() 方法,并立即通过 ChannelRoute.model() 方法,可能在你的 ajax 完成之前。在这种情况下,您可以让 ChannelRoute.model() 方法创建一个临时 Channel(例如,没有节目)并将其放入 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,但大体相同。)

    临时对象的更新实际上展示了 ember 的一个非常酷的方面,即您的 ui 可能会显示来自临时对象的值,但是当您的 ajax 调用完成并且频道和程序都已加载时 -您的用户界面将正确更新。只需确保您使用 set() 方法更新您的对象,并且您的 ui 模板很乐意使用部分数据。

    【讨论】:

    • 这是很棒的东西,谢谢。关于您在存储和路线上的观点,这一切都将发生在一条路线上(它是一个交互式网格)。因此,我可能会将所有内容都连接到 setupController 方法中。一旦获取了两组 JSON,您将如何创建程序模型并将它们与每个通道相关联?
    • each 方法的某些版本会照顾你。例如,jQuery 的 each 将允许您运行程序 json,给出 channels 数组的每个元素的索引和值。这将为您提供连接到您的频道 json 所需的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 2011-05-24
    相关资源
    最近更新 更多