使用updateFromJS会在应该添加值时替换它们

我有这个代码:

var attachmentsModel = { convAttachments: ko.mapping.fromJS([]) }; $(function() { ko.applyBindings(attachmentsModel) refreshConvAttachments(); }); function refreshConvAttachments() { $.ajax({ url: '/xxxxxxx/', success: function (dataJS) { // Send KO the data ko.mapping.updateFromJS(attachmentsModel.convAttachments, dataJS); } }); } 

上面的AJAX调用返回:

 [{ "title": "BillGates", "added_by": "xxx", "thumb": "urlhere", "id": 410, "link": "/link/410", "added_on": "2011-02-22T12:57:09-08:00" }, { "title": "biz-stone", "added_by": "xxx", "urlhere", "id": 411, "link": "/link/411", "added_on": "2011-02-22T12:57:53-08:00" }] 

这很好用。 之后,虽然用户能够添加附件,但这就是它正在破坏的地方。 虽然它将新附件添加到模式并在页面上显示,但它会删除attachmentsModel.convAttachments中所有先前加载的项目。

稍后,会发生这种情况:

 ko.mapping.updateFromJS(attachmentsModel.convAttachments, file); 

Ajax返回:

 [{ "title": "eric_schmidt", "added_by": "xxx", "thumb": "xxxxxx", "id": 417, "link": "/link/417", "added_on": "2011-02-22T13:16:45-08:00" }] 

我希望明确一点,如果不是,请告诉我。 当我使用updateFromJS时,为什么knockoutjs会杀死所有东西?

ko.mapping.updateFromJS()希望您收到最初使用ko.mapping.fromJS()准备的项目的完整列表。 原始文件中缺少的任何项目都被视为已删除,更新中的任何新项目都被视为添加项目。 因此,目前映射插件不允许您以这种方式进行增量更新。

如果您正在进行增量更新,最好的办法是找到需要更新的项目,并完全替换它们或替换每个项目上的单个可观察项目。

你可以随时尝试使用

 $.extend(attachmentsModel.convAttachments,ko.mapping.fromJS(dataJS)); 

虽然我不太确定是否会正确更新所有绑定,但您可能必须通过调用来回复绑定

 ko.applyBindings(attachmentsModel)