如何在运行中扩展映射的knockout viewmodel""附加财产?

时间:2016-01-07 15:31:19

标签: javascript asp.net-web-api knockout.js knockout-mapping-plugin

我从ASP.NET Web API获取了一个json对象数组,并将其映射到我的knockout viewmodel(ko.observablearray)。在将模型绑定到文档时,我得到了一个"无法处理绑定"错误。

这是因为我从API doesen获得的json没有定义Editable属性。如何在映射时动态添加它?它默认为false

以下是代码:

var Accessory = function (id, leftOnPatient, reject, amount, patchNumber, additionalInfo, editable) {
  var self = this;

  self.Id = ko.observable(id);
  self.LeftOnPatient = ko.observable(leftOnPatient);
  self.Reject = ko.observable(reject);
  self.Amount = ko.observable(amount);
  self.PatchNumber = ko.observable(patchNumber);
  self.AdditionalInfo = ko.observable(additionalInfo);
  self.Editable = ko.observable(editable); 
}

function MedicinesAndAccessoriesViewModel() {
  var self = this;

  self.Accessories = ko.observableArray([]);
  self.error = ko.observable();

  function getAllAccessories() {
    ajaxHelper(accessoriesUri, 'GET').done(function (data) {
      ko.mapping.fromJS(data, {}, self.Accessories);     
    });
  };

  getAllAccessories(); 
};

var vm = new MedicinesAndAccessoriesViewModel();
ko.applyBindings(vm, document.getElementById("medicinesAndAccessoriesTab"));

HTML:

<ol class="list-group list_of_items padding-top-15" data-bind="foreach: Accessories">
        <li class="list-group-item">
            <div class="container-fluid">
                <div class="col-md-4">
                    <span data-bind="text: Id, visible: !Editable()"></span> //Here I get the error
....
...
..
.

那么,如何为从API加载的每个Editable(false)定义Accessory属性客户端?我从API加载的dto获得的每个其他属性。可以在映射时以某种方式完成吗?

1 个答案:

答案 0 :(得分:1)

您目前根本没有在任何地方使用Accessory构造函数,这个词只会在您的代码段中定义一次...

您需要利用映射定义并告诉它正确映射json的那部分,例如:

function getAllAccessories() {
    ajaxHelper(accessoriesUri, 'GET').done(function (data) {
        var mappingRules = {
            'accessories': {
                create: function(options) {
                    return new Accessory(
                        options.data.id, 
                        options.data.leftOnPatient, 
                        options.data.reject, 
                        options.data.amount, 
                        options.data.patchNumber, 
                        options.data.additionalInfo, 
                        options.data.editable);
                }
            }
        };

        ko.mapping.fromJS(data, mappingRules, self.Accessories);     
    });
};

这应该已经确保Editable可观察到了。您可以尝试使用!!将其强制为布尔值,以防万一:

self.Editable = ko.observable(!!editable); 

PS。我建议通过将参数的数量减少到一个(例如datadto)来使构造函数稍微复杂一些,这样return new Accessory(options.data)将在上面的代码片段中完成。