【问题标题】:Combine Multiple Web Service Results into a Single Knockout ViewModel将多个 Web 服务结果合并到单个 Knockout ViewModel
【发布时间】:2012-06-03 02:10:45
【问题描述】:

我需要调用多个 Web 服务来获取有关资源的不同信息。例如,我可能对多租户应用程序有以下调用:

  1. 获取位置
  2. 获取位置/{id}/服务器
  3. 获取位置/{id}/租户

对于这些调用中的每一个,我都会对相应的 Web 服务进行不同的 jQuery ajax 调用。但是,我的 UI 显示了一个汇总页面,其中显示了每个查询结果的表格。构建一个单独的 Knockout ViewModel 似乎真的很容易,然后每个查询结果都有 ObservableArrays 但也许我正在错误地处理这个问题。无论哪种方式,我都不确定如何将多个调用合并到一个模型或为每个调用使用多个模型。

有没有人可以分享任何文档或示例代码来为我指明正确的方向?

更新:我想在我的 Knockout 对象中实现这个最终结果/结构。本质上,它是一对多关系,一个位置与多个服务器或租户。

LOCATION
  - Name
  - ID
  - Date
  - Servers []
  - Tenants []

谢谢

【问题讨论】:

  • @Steve 我已经尝试了这两种方法,但主要是创建两个不同的模型。它们绑定好,但是我的显示器相互混合,因此分配绑定上下文不起作用,无法渲染。在我看来,单一模型是最好的方法,但我不知道如何在父绑定到 Web 服务后绑定子数组。

标签: jquery rest knockout.js asp.net-web-api


【解决方案1】:

我所做的是为页面创建一个视图模型,并使用每次调用的值更新属性。我使用带有三个参数的 ko.mapping 插件来更新现有的可观察数组并使属性可观察。 ko.mapping.fromJSON 调用将进入您的 AJAX 调用的成功函数,您可以在其中获得结果,为了简单起见,我只是让它们单击处理程序。 http://jsfiddle.net/jgoemat/v9XTf/

var jsonLocations = '[{"name":"home"},{"name":"work"}]';
var jsonServers = '[{"name":"Mercury"},{"name":"Venus"}]';
var jsonTenants = '[{"name":"Betty"},{"name":"Frank"}]';

function ViewModel() {
    var self = this;
    self.locations = ko.observableArray();
    self.servers = ko.observableArray();
    self.tenants = ko.observableArray();

    self.loadLocations = function() { ko.mapping.fromJSON(jsonLocations, {}, self.locations); };
    self.loadServers  = function() { ko.mapping.fromJSON(jsonServers, {}, self.servers); };
    self.loadTenants = function() { ko.mapping.fromJSON(jsonTenants, {}, self.tenants); };
}

var my = { vm: new ViewModel() };                                                        

ko.applyBindings(my.vm);​

编辑 - Updated Fiddle

如果位置包含租户,您可以修改位置上的该属性,ko 事件处理程序将当前模型传递给处理程序:

self.loadServers  = function(location) {
    ko.mapping.fromJSON(jsonServers, {}, location.Servers);
};

如果您使用 jQuery 进行绑定,则可以使用 ko.dataFor(element) 从元素所在的上下文中获取模型:

$('.loadAll').live('click', function(e) {
    var location = ko.dataFor(this);
    // location can be used in success callback of ajax 
    ko.mapping.fromJSON(jsonServers, {}, location.Servers);
    ko.mapping.fromJSON(jsonTenants, {}, location.Tenants);
});

【讨论】:

  • 这有点帮助。问题是结构。本质上,只有一个位置具有几个标准的可观察属性,例如名称、ID 等,然后包含服务器和租户的数组。我已经用我正在寻找的结构更新了 OP。我将如何转换您的样本以使其发挥作用?
  • 感谢您的解释和示例。这为我指明了正确的方向,但是我开始质疑我是否要继续沿着 JS 路径前进,而不是在服务器端传递静态类型的对象。在淘汰赛方面解析嵌套对象似乎需要做很多工作。
【解决方案2】:

如果我没听错的话,你有一个带有 observableArray 位置的视图模型。每个位置可能有一组服务器和一组租户。解决这个问题的一种方法是创建一个存储所有返回值的对象。所以在那个对象中你可能有 {locations: [], servers: [], tenants: []} 。这都是对象的主根。

获得位置后,将它们映射到可观察对象的本地模型。向 location 对象添加一个名为 servers 的属性。这将用于导航到该位置的服务器。服务器属性可以执行搜索(速度较慢但适应性更强)或使用备忘录对象来查找位置的索引。关键是在内存中设置这个本地对象,以帮助跟踪您的数据并保持导航正常工作。

另一种选择是简单地将每个位置的服务器加载到客户端上它们各自的位置对象中。无论哪种方式,您都可以在客户端上创建自己的模型。我很少准确地接受服务器给我的东西,而不是映射到某些东西。顺便说一句 - 我不为此使用映射插件,但我想你可以。

【讨论】:

    猜你喜欢
    • 2021-08-21
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多