Wix复选框变更无法更新CMS字段值,回调报错索引未找到
错误现象
- 勾选复选框时:
UserError: An error occurred in one of undefined callbacks
Caused by cannot update field values: index not found
Caused by: cannot update field values: index not found
- 取消勾选复选框时:
No current item found in dataset. Retrying after dataset refresh...
UserError: An error occurred in one of undefined callbacks
Caused by TypeError: Cannot read properties of undefined (reading 'then')
Caused by: TypeError: Cannot read properties of undefined (reading 'then')
代码目标
根据fieldName(布尔类型字段)的状态,更新对应resultField的值,实现复选框状态变更时,页面上的resultField同步更新。
测试代码
$w.onReady(() => { $w("#dynamicDataset").onReady(() => { try { const dataset = $w("#dynamicDataset"); const currentItem = dataset.getCurrentItem(); if (!currentItem) { console.warn("No current item found in dataset."); return; } // Log current item for debugging console.log("Current Item from CMS:", currentItem); // Define the array that maps dataset fields to their corresponding checkbox IDs const checkboxMappings = [ { fieldName: "inspiration", checkboxID: "#inspirationcheckbox"}, { fieldName: "strengthSavingThrowProficiency", checkboxID: "#strengthcheckbox" , resultField: "strengthSavingThrow", modifier: "strength1"}; console.log("Dataset is ready."); checkboxMappings.forEach(mapping => { const { fieldName, checkboxID } = mapping; const checkbox = $w(checkboxID); if (!checkbox) { console.warn(`Checkbox with ID ${checkboxID} not found.`); return; } const value = currentItem[fieldName] || false; // Default to false checkbox.checked = !!value; // Debugging logs console.log(`Checkbox ${checkboxID} set to ${!!value} for ${fieldName}`); checkbox.onChange(() => handleCheckboxChange(dataset, mapping)); }); } catch (error) { console.error("Error initializing checkboxes:", error); } }); }); function handleCheckboxChange(dataset, mapping) { const { fieldName, checkboxID, resultField, modifier } = mapping; if (!resultField) { console.error("Mapping is missing resultField:", mapping); return; } // const checkbox = $w(checkboxID); // if (!checkbox) { // console.error(`Checkbox ${checkboxID} not found.`); // return; // } // const isChecked = checkbox.checked; dataset.onReady(() => { const currentItem = dataset.getCurrentItem(); if (!currentItem) { console.error("No current item found in dataset. Retrying after dataset refresh..."); dataset.refresh() .then(() => handleCheckboxChange(dataset, mapping)) // Retry after refresh .catch(err => { console.error("Failed to refresh dataset:", err); }); return; } const isChecked = currentItem[fieldName] || false; const baseValue = currentItem[modifier] || 0; const proficiencyBonus = currentItem.proficiencyBonus; const updatedValue = isChecked ? baseValue + proficiencyBonus : baseValue; dataset.setFieldValue(resultField, updatedValue) .then(() => { console.log(`${resultField} successfully updated to ${updatedValue}`); }) .catch(err => { console.error(`Error updating field ${resultField}:`, err); }); }); }
修复建议
1. 修复数组语法错误
checkboxMappings数组的第二个对象末尾误用了分号;,需改为逗号,,否则数组定义会直接失败:
const checkboxMappings = [ { fieldName: "inspiration", checkboxID: "#inspirationcheckbox"}, { fieldName: "strengthSavingThrowProficiency", checkboxID: "#strengthcheckbox", resultField: "strengthSavingThrow", modifier: "strength1"} ];
同时第一个mapping对象缺少resultField和modifier字段,会触发handleCheckboxChange的错误分支,要么补充对应字段,要么初始化时过滤掉这类不完整的mapping:
checkboxMappings.forEach(mapping => { if (!mapping.resultField || !mapping.modifier) { console.warn("Skipping mapping with missing required fields:", mapping); return; } // 后续初始化逻辑... });
2. 移除handleCheckboxChange中的重复dataset.onReady绑定
数据集已经在页面初始化阶段完成就绪,在回调里重复绑定onReady会导致逻辑混乱,直接获取当前数据即可:
function handleCheckboxChange(dataset, mapping) { const { fieldName, checkboxID, resultField, modifier } = mapping; if (!resultField || !modifier) { console.error("Mapping is missing required fields:", mapping); return; } const checkbox = $w(checkboxID); if (!checkbox) { console.error(`Checkbox ${checkboxID} not found.`); return; } const isChecked = checkbox.checked; const currentItem = dataset.getCurrentItem(); if (!currentItem) { console.error("No current item found in dataset."); return; } const baseValue = currentItem[modifier] || 0; const proficiencyBonus = currentItem.proficiencyBonus || 0; // 增加默认值避免undefined参与计算 const updatedValue = isChecked ? baseValue + proficiencyBonus : baseValue; dataset.setFieldValue(resultField, updatedValue) .then(() => { console.log(`${resultField} successfully updated to ${updatedValue}`); }) .catch(err => { console.error(`Error updating field ${resultField}:`, err); }); }
3. 直接从复选框获取状态,而非数据集
复选框变更后,数据集内的currentItem不会立即同步更新,直接读取复选框的checked属性才能保证状态的实时性,避免逻辑偏差。
4. 修复dataset.refresh的Promise调用问题
dataset.refresh()在部分场景下可能不返回Promise,导致.then()调用报错。如果需要重试获取数据,可改用getCurrentItemAsync()替代刷新,同时避免无限递归:
if (!currentItem) { console.error("No current item found in dataset."); dataset.getCurrentItemAsync() .then(item => { if (item) { const baseValue = item[modifier] || 0; const proficiencyBonus = item.proficiencyBonus || 0; const updatedValue = isChecked ? baseValue + proficiencyBonus : baseValue; return dataset.setFieldValue(resultField, updatedValue); } }) .catch(err => console.error("Failed to get current item:", err)); return; }
5. 确保数据集处于可编辑状态
setFieldValue要求数据集处于编辑模式,若为只读状态会直接报错。可在更新前调用dataset.edit()切换状态:
dataset.edit() .then(() => dataset.setFieldValue(resultField, updatedValue)) .then(() => { console.log(`${resultField} successfully updated to ${updatedValue}`); // 若需保存到数据库,可调用dataset.save() // return dataset.save(); }) .catch(err => { console.error(`Error updating field ${resultField}:`, err); });
内容的提问来源于stack exchange,提问作者BabyPangolin

