2013-02-20 174 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 
 
    } 
 
    //[...] 
 
}