按数据类型自定义Knockout Mapping分组映射问题
嘿,我刚好碰到过类似的问题!你现在的问题应该是在自定义映射的回调里,每次处理单个对象时都新建了一个数组,导致每个对象都单独占一个数组。别担心,有两种靠谱的解决办法,看你哪种更适配你的场景:
方案一:先预处理原始数据再映射
这种方法简单直接,先把你的原始数据按description字段分组,再交给Knockout Mapping插件处理,这样就能直接得到你想要的分组数组。
举个具体的例子,假设你的原始数据是这样:
const rawData = [ { id: 1, description: "Group A", value: "foo" }, { id: 2, description: "Group A", value: "bar" }, { id: 3, description: "Group B", value: "baz" }, { id: 4, description: "Group C", value: "qux" }, { id: 5, description: "Group C", value: "quux" } ];
先通过reduce方法完成分组:
// 按description字段分组原始数据 const groupedData = rawData.reduce((acc, item) => { // 如果当前分组不存在,就初始化一个空数组 if (!acc[item.description]) { acc[item.description] = []; } // 将当前对象推入对应分组的数组 acc[item.description].push(item); return acc; }, {});
然后直接用Knockout Mapping映射这个分组后的对象:
const viewModel = ko.mapping.fromJS(groupedData);
这样viewModel里就会生成三个可观察数组:GroupA、GroupB、GroupC,每个数组里包含对应分组的所有对象,完全符合你的预期!
方案二:用自定义映射+缓存实现动态分组
如果你需要在映射过程中对每个对象做额外的转换处理(比如修改属性格式、添加计算属性),可以用这种方法:通过一个缓存对象来跟踪已创建的分组数组,在create回调里判断当前对象属于哪个分组,将其加入对应的数组。
代码示例如下:
// 定义一个缓存对象,用来存储已创建的分组可观察数组 const groupCache = {}; // 配置Knockout Mapping的自定义映射规则 const mappingOptions = { '': { create: function(options) { // 先将当前原始对象映射为Knockout可观察对象 const mappedItem = ko.mapping.fromJS(options.data); const itemDesc = mappedItem.description(); // 检查缓存中是否已有该分组的数组 if (!groupCache[itemDesc]) { // 没有的话创建新的可观察数组并存入缓存 groupCache[itemDesc] = ko.observableArray(); } // 将当前对象推入对应分组的数组 groupCache[itemDesc].push(mappedItem); // 返回映射后的对象(这一步只是触发分组逻辑,最终我们用的是groupCache里的分组) return mappedItem; } } }; // 先映射原始数组,触发每个对象的create回调,填充groupCache ko.mapping.fromJS(rawData, mappingOptions); // 最后将缓存的分组转为可观察的viewModel const viewModel = ko.mapping.fromJS(groupCache);
这种方法的好处是可以在映射每个对象时做个性化处理,同时完成分组逻辑,适合复杂场景。
两种方案都能解决你的问题,优先推荐方案一,因为它更高效、代码更简洁;如果有额外的映射需求,再考虑方案二。
内容的提问来源于stack exchange,提问作者weirdoCaps
相关产品推荐
相关产品推荐

