How to exclude certain properties from Knockoutjs toJS()

这一生的挚爱 提交于 2019-12-04 00:36:51

Have you tried the ignore keyword? It has a similar usage to the include:

var mapping = {
    'ignore': ["propertyToIgnore", "alsoIgnoreThis"]
}
var viewModel = ko.mapping.toJS(data, mapping);

You could just use ignore when you do the original mapping of the server data, then it won't be on your object at all when you convert it back to JS.

If we have a complex object model instance under vm.Payment observable reference as:

{
    "Summary": { 
        "Count": 12,
        "PaymentAmount": 1500,
        "PaymentMethod": "Cheque",
        "PaymentDate": "2015-04-08T22:38:48.552Z",
        "AgentOid": 1208795,
        "AgentName": "Asere Ware"
    }
    //[...]
}

and need to ignore only some inner properties, then:

var mapping = {
    'ignore': ['Summary.PaymentMethod', 'Summary.PaymentDate'] //avoid lost some initialized values.
};
// map updating existing observable (Payment) under my ViewMode (vm) with source "data" JSON object.
ko.mapping.fromJS(data, mapping, vm.Payment);

and this is the result for vm.Payment content, where only PaymentMethod and PaymentDate are keept:

{
    "Summary": { 
        "Count": 0,
        "PaymentAmount": 0,
        "PaymentMethod": "Cheque",
        "PaymentDate": "2015-04-08T22:38:48.552Z",
        "AgentOid": undefined,
        "AgentName": undefined
    }
    //[...]
}

Ok, I've figured out one solution that works though I'm hoping there's a better approach. The trick is to ignore these fields in the mapping plugin, then add them in manually as computed fields. Computed fields will never end up in the generated JavaScript object when toJS is called.

// Utility function to quickly generate a computed field
ko.readonly = function (value)
{
   return ko.computed(function ()
   {
      return value;
   });
};

// View Model
var ViewModel = function (project)
{
   var readonly = ['B', 'C', 'D']; // Fields I want to ignore
   var mapping = {
      'ignore': readonly //Read-only properties, we'll add these manually as computed fields
   };

   // Use Mapping plugin to make everything observable, except the fields above
   ko.mapping.fromJS(project, mapping, this);

   // Now loop through the read only array and add these fields in as computed
   for(var i = 0; i < readonly.length; i++)
   {
      var field = readonly[i];
      this[field] = ko.readonly(project[field]);
   }
}

I can now bind to these view model as normal:

ko.applyBindings(new ViewModel(data));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!