代码之家  ›  专栏  ›  技术社区  ›  Mathew A

将从服务器接收的对象转换为具有ko可观察属性的对象

  •  0
  • Mathew A  · 技术社区  · 10 年前

    我对一个看似简单的想法有意见。

    我正在尝试创建 ko.observable() 是从服务器提供的数据动态生成的。

    服务器正在向我发送一个~240值的JSON数组。我想为每个人创建一个可观察的,因为我把他们放在一个在线表格中。

    第一次尝试

    function AppViewModel() {
    
      var self = this;
    
      var data = {};
    
      $.getJSON("/record/20001", function(data) {
        $.each(data, function(i, val) {
          self.data[i] = ko.observable(val);
        });
      });
    
    
      self.test = 5;
    
      self.test2 = ko.observable(69);
    
    
    }
    
    vm = new AppViewModel();
    ko.applyBindings(vm);
    

    因此,我无法访问任何数据。

    第二次尝试有效

    function AppViewModel() {
    
        var self = this;
        self.abnorm_comment = ko.observable();
        self.abnorm_test1 = ko.observable();
        self.abo_sys_spec = ko.observable();
        self.access_location = ko.observable();
        self.ace_inhibit = ko.observable();
    
        /* 
        A myriad of line like these, written by hand
        */
    
        self.xray_other = ko.observable();
    
    
        $.getJSON("/record/20001", function (data) {
            $.each(data, function (i, val) {
                self[i](val);
            });
        });
    
        self.test = 5;
    
        self.test2 = ko.observable(69);
    
    
    }
    

    我想做的事

    function AppViewModel() {
    
        var self = this;
    
        var data = {};
    
    
        $.getJSON("/record/20001", function (data) {
            $.each(data, function (i, val) {
                self.data[i] = ko.observable(val);
            });
        });
    
    }
    

    并按如下方式访问:

    <input type="text" data-bind="value: data.case_id">
    

    第一次尝试,我的视图模型中没有数据。如果我拉起 vm 变量,但它确实有数据。

    我是不是做错了什么?第二种工作方式看起来不太好,有这么多可观察的东西。

    如果我遗漏了明显的东西,请告诉我

    个人解决方案

    最后,我在应用绑定和AJAX服务器请求之间遇到了竞争条件。我最后也使用了@JotaBe推荐的插件

    2 回复  |  直到 10 年前
        1
  •  2
  •   Geoff    10 年前

    这在过去对我来说是可靠的:

    jsonToObservable = function (obj, data) {
    
        for (var p in data) {
            var temp = data[p];
    
            obj[p] = ko.observable(temp);
    
        }
    };
    
        2
  •  1
  •   JotaBe    10 年前

    您可以使用 ko.mapping 插件,它将为你做这件事。

    优点是这个插件经过了很好的测试,能够映射更复杂的数据,如数组或嵌套属性。

    您可以从JSON映射,也可以从已经实例化的JavaScript对象映射。synatx简单如下:

    var viewModel = ko.mapping.fromJSON(data);
    

    另一个优点是,它还可以根据来自服务器的新更新数据更新本地映射副本,而无需重建整个对象。这也有助于更新视图,而无需重建(或解除绑定)视图。

    最后一个优点是,如果您需要将JSON或JavaScript对象发布回服务器,它还可以取回它,如下所示:

    var unmapped = ko.mapping.toJS(viewModel);