如何在Knockout视图模型中生成仅含修改字段的增量请求负载?
实现Knockout视图模型仅提交修改字段的方案
好问题!正好Knockout的mapping插件本身就内置了追踪数据变更的能力,完全不用额外引入其他框架,我来给你一步步说明怎么实现:
1. 初始化视图模型时开启变更追踪
默认情况下,ko.mapping.fromJS不会记录字段的修改状态,所以我们需要在初始化时配置trackChanges: true选项,让插件帮我们追踪哪些字段被修改过:
var data = { "firstName": "John", "lastName": "Doe" }; // 配置mapping选项,开启变更追踪 var mappingOptions = { trackChanges: true }; var viewModel = ko.mapping.fromJS(data, mappingOptions);
开启这个配置后,每个生成的可观察对象都会附带一个isDirty()方法,你也可以通过这个方法单独判断某个字段是否被修改过,比如viewModel.firstName.isDirty()会返回true或false。
2. 生成仅包含修改字段的提交负载
当需要向服务器提交数据时,我们可以使用ko.mapping.toJS(或ko.mapping.toJSON)并传入includeDirty: true的选项,这样只会导出被修改过的字段:
// 获取仅含修改字段的JS对象 var changedPayload = ko.mapping.toJS(viewModel, { includeDirty: true }); // 如果需要直接生成JSON字符串,用toJSON更方便 var changedJsonPayload = ko.mapping.toJSON(viewModel, { includeDirty: true });
比如你修改了firstName为"Jane",此时changedPayload就是{ "firstName": "Jane" },完全符合你想要的提交格式。
3. 提交成功后重置变更状态
当服务器确认更新成功后,你可以调用ko.mapping.resetDirty(viewModel)来重置所有字段的脏状态,这样下次提交时就只会追踪新的修改,不会包含之前已经提交过的变更:
// 假设这里是你的AJAX提交逻辑 fetch('/api/user', { method: 'PUT', body: changedJsonPayload, headers: { 'Content-Type': 'application/json' } }) .then(response => response.json()) .then(() => { // 提交成功后重置脏状态 ko.mapping.resetDirty(viewModel); });
额外说明
这个方案同样支持嵌套对象的场景,比如你的数据里有嵌套的address对象,mapping插件会递归追踪嵌套字段的变更,生成的提交负载也只会包含嵌套结构中被修改的部分,非常省心。
内容的提问来源于stack exchange,提问作者Neel
相关产品推荐
相关产品推荐

