【问题标题】:Convert object received from server into object with ko observable properties将从服务器接收到的对象转换为具有 ko 可观察属性的对象
【发布时间】:2016-04-15 22:07:37
【问题描述】:

我对看似简单的想法有疑问。

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

服务器正在向我发送一个 ~240 值的 JSON 数组。当我将它们放入在线表单时,我想为每一个创建一个 observable。

第一次尝试

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">

第一次尝试我的视图模型中没有数据。如果我在 Chrome 控制台中调出 vm 变量,它确实有数据。

我在这里做错了吗?第二种可行的方式在有这么多可观察对象时看起来不太好。

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

个人解决方案

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

【问题讨论】:

    标签: javascript knockout.js knockout-mapping-plugin


    【解决方案1】:

    这在过去对我来说很可靠:

    jsonToObservable = function (obj, data) {
    
        for (var p in data) {
            var temp = data[p];
    
            obj[p] = ko.observable(temp);
    
        }
    };
    

    【讨论】:

    • 当心:此解决方案将无法正确映射数组(如果它们来自服务器)和嵌套属性(如果服务器返回嵌套对象)。因此,这仅适用于来自服务器的简单对象,该对象仅包含非数组属性..
    • @JotaBe 服务器只提供了一个简单的对象。所以这会起作用。谢谢!
    【解决方案2】:

    您可以使用ko.mapping 插件,它会为您完成。

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

    您可以从 JSON 或已经实例化的 JavaScript 对象进行映射。语法就这么简单:

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

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

    最后一个优点是,如果您需要将 JSON 或 JavaScript 对象发送回服务器,它还允许取回它,就像这样:

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

    【讨论】:

    • 如果我使用插件,向我的 ViewModel 添加附加功能的最佳方式是什么?即计算变量。
    • 您可以稍后在创建的对象上简单地添加功能。例如:viewmodel.doubleX = ko.computed(function() { return 2*viewModel.x(); }); 如您所见,您可以使用现有的viemodel 变量访问属性。在这种情况下,您也可以使用此模式,如计算的 observable 文档中所述:viewmodel.doubleX = ko.computed(function() { return 2*this.x(); }, viewModel);
    • 如果遇到麻烦,请创建一个新问题。
    • 不,那太好了。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多