2012-03-09 90 views
6

我一直試圖弄清楚現在已經有相當長的一段時間了。我找不到解決這個問題的任何問題,但如果我錯了,請糾正我。KnockoutJS:使用映射將數據更新/插入到視圖模型

問題: 我有一個來自JSON API的數據,嵌套的數組/對象結構。我使用映射來最初用我的數據填充模型。爲了更新這個,我想在新數據到達時擴展模型,或更新現有數據。

據我發現,映射選項鍵,應該爲我做這個技巧,但我可能誤解了映射選項的功能。

我歸結問題通過這個例子來表示:

var userMapping = { 
    key: function(item) { 
     return ko.utils.unwrapObservable(item.id); 
    } 
}; 

// JSON call replaced with values 
var viewModel = { 
    users: ko.mapping.fromJS([], userMapping) 
}; 

// Should insert new - new ID? 
ko.mapping.fromJS([{"id":1,"name":"Foo"}, {"id":2,"name":"Bar"}], userMapping, viewModel.users); 

// Should only update ID#1 - same ID? 
ko.mapping.fromJS([{"id":1,"name":"Bat"}], userMapping, viewModel.users); 

// Should insert new - New ID? 
ko.mapping.fromJS([{"id":3,"name":"New"}, {"id":4,"name":"New"}], userMapping, viewModel.users); 

ko.applyBindings(viewModel);​ 

小提琴:http://jsfiddle.net/mikaelbr/gDjA7/

正如你可以看到,第一行插入數據。都好。但是當我嘗試更新時,它會替換內容。對於第三種映射也是如此;它取代了內容,而不是擴展它。

我用錯了嗎?我應該嘗試在使用映射之前「手動」擴展內容嗎?

編輯解決方案:
我由具有第二輔助陣列中存儲的所有當前模型解決了這個情況。在新數據上我擴展了這個數組,並更新了視圖模型以包含累積項目。

在更新(在我的情況下是一個WebSocket消息),我循環遍歷模型,更改了有問題的項目的內容,並使用方法valueHasMutated()將更改值通知給Knockout庫。

回答

4

從看你的示例代碼映射插件行爲正是我希望它。當您在集合上調用fromJS時,您正在有效地告訴映射插件,這是該集合的新內容。例如:

在第二行,它如何知道您是否正在更新或者您是否簡單地刪除了id:2?

我找不到任何提及將數據視爲更新的合適方法,儘管您可以添加一個。映射陣列附帶一些有用的方法,例如mappedIndexOf可幫助您查找特定項目。如果您收到一個更新數據集,只需循環遍歷它即可找到該項目,並使用mapping.fromJS調用將其更新爲該特定項目。這可以很容易地推廣到可重用的方法。

+0

是的。這或多或少是我解決它的方法。 – mikaelb 2012-03-09 17:18:12

+0

對此的任何想法:http://stackoverflow.com/questions/20397054/knockout-js-mapping-keys-and-kendo-ui-grid – jtromans 2013-12-05 10:26:30

0

是的,您應該首先將所有數據收集到列表或數組中,然後將映射應用到該列表。否則,你將覆蓋viewModel中的值。

1

您可以使用ko.mapping.updateFromJS()更新現有值。但是,它不會添加新值,因此在您的實例中會出現問題。看看下面的鏈接瞭解更多詳情。

Using updateFromJS is replacing values when it should be adding them

+4

2011年8月updateFromJS()方法被刪除。https://github.com/SteveSanderson/knockout.mapping/commit/bff3c1864a5fd45289933b35de1ef70af4aed6b5 – mikaelb 2012-03-09 16:50:58

+0

+1 @mikaelb - 我沒有意識到這一點。謝謝(你的)信息。 – 2012-03-09 16:55:49

相關問題