2013-02-20 167 views
14

我有以下型号:如何排除Knockoutjs toJS()某些性质

var model = { 
    A: 'One', 
    B: 'Two', 
    C: 'Three' 
}; 

我结合各种UI元素,以这些领域,它的伟大工程。不过,我转换模型回JavaScript对象,所以我可以保存到服务器的任何变化:

var goingToServer = ko.toJS(model); 

goingToServer将包括性质A,B和C.然而,假设属性C是数据的大块那永远不会改变。我想避免将其发送回服务器。

有没有办法让toJS()只有在将模型转换回JavaScript对象时包含一组预定义的字段?

我一直在调查的一件事是Knockout Mapping plugin。它有一个叫做设置包括其被记录为,例如:

当转换视图模型回JS对象,默认情况下 映射插件将仅包含属于你的 原始视图模型的一部分属性,除非它还包含 淘汰赛生成的_destroy属性,即使它不是您原始对象的一部分。但是,您可以选择自定义这个数组:

但是,它出现在一个include阵列的['A', 'B']作为证明这个插件不起作用,因为ko.mapping.toJS()仍然将包括A,B和C,即使我通过。我猜这个功能的目的是包括额外的字段,这些字段不在原始模型中。

当将模型转换回JavaScript对象时,有没有办法排除某些属性,做了一些hacky之类的事情,比如生成对象并手动删除我不想在发送到服务器之前的属性?

回答

23

您是否试过ignore关键字?它有一个类似的使用的包括:

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

你可以只使用忽略,当你做服务器数据的原始映射,那么它会不会是你的目标时都当你将其转换回JS 。

+0

那是不行的,因为那么你就不能绑定到它。 – 2013-02-20 19:47:50

+0

你试过了吗?由于文档没有提到在返回JS对象时是否可以使用忽略。 – 2013-02-20 20:02:25

+0

是的,我刚试过。当我忽略字段Notes时,当我调用applyBindings时,我立即发现在模型中找不到Notes字段。 – 2013-02-20 20:04:24

2

好吧,我已经想出了一种解决方案,虽然我希望有更好的方法。诀窍是忽略映射插件中的这些字段,然后将它们手动添加为计算字段。当调用toJS时,计算的字段永远不会结束生成的JavaScript对象。

// 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]); 
    } 
} 

我现在可以绑定到这些视图模型为正常:

ko.applyBindings(new ViewModel(data)); 
3

如果我们在虚拟机有一个复杂的对象模型实例。付款观察到引用作为:

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

和需要忽略仅一些内的属性,则:

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);

,这是针对VM的结果。付款内容,只有PaymentMethod和PaymentDate需要保留:

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