将多个Web服务结果合并到单个Knockout ViewModel中

时间:2012-05-28 18:53:04

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

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

  1. 获取地点
  2. 获取位置/ {id} / servers
  3. 获取位置/ {id} /租户
  4. 对于这些调用中的每一个,我最终都会对相应的Web服务进行不同的jQuery ajax调用。但是,我的UI显示了一个排序摘要页面,显示了每个查询结果的表格。看起来很容易构建一个Knockout ViewModel,然后为每个查询结果都有ObservableArrays,但也许我正在接近这个错误。无论哪种方式,我都不确定如何将多个呼叫合并到一个模型或为每个呼叫使用多个模型。

    有没有人有他们可以分享的任何文件或示例代码,以指引我朝正确的方向发展?

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

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

    由于

2 个答案:

答案 0 :(得分:1)

我所做的是为页面创建一个视图模型,并使用每次调用的值更新属性。我使用带有三个参数的ko.mapping插件来更新现有的observable数组并使属性可观察。 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);
});

答案 1 :(得分:0)

如果我没有正确地听到您的声音,那么您将拥有一个带有observableArray位置的viewmodel。每个位置可能有一组服务器和一组租户。解决此问题的一种方法是创建一个存储所有返回值的对象。所以在那个对象中你可能有{locations:[],servers:[],tenants:[]}。这都是对象的主要根源。

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

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