1

我有一个剑道网格,我有一个可编辑的细节模板。在详细信息模板中,我有一个多选。

保存时,我手动更新 dataItem 以获取详细信息模板的多选中的最新选项。从多选中抓取数据没有问题。在我触发网格进行保存之前,一切实际上看起来都不错。

我使用以下代码将多选项目添加到网格的 dataItem 中:

function SaveRefItemSubCategories() { //Called on Save button click
    var grid = $("#RefItemSubCategoryGrid").data("kendoGrid");

    for (var i = 0; i < grid.dataSource._data.length; i++) {
        var dataItem = grid.dataSource._data[i];
        dataItem.RefItemCategoryServiceIDs = [];
        var ms = $("#MultiSelect_" + dataItem.uid).data("kendoMultiSelect");
        var values = ms.value();

        for(var x = 0; x < values.length; x++) {
            dataItem.RefItemCategoryServiceIDs.push(values[i]);
        }
    }
    grid.dataSource.sync();
}

那时,当我查看发布到服务器的内容时​​,网格的数据源对于序列化的多选项目如下所示:

模型[0].RefItemCategoryServiceIDs[] 15

&models%5B0%5D.RefItemCategoryServiceIDs%5B%5D=15

它应该如下所示:

模型[0].RefItemCategoryServiceIDs[ 0 ] 15

&models%5B0%5D.RefItemCategoryServiceIDs%5B 0 %5D=15

抱歉,那里有多余的空间,否则我无法将其加粗

序列化数据中缺少数组索引会导致该属性在访问服务器时为空。此属性的类型是列表

我尝试了几种不同的方法,但最终在我第一次保存后在 dataItem 上创建了新的属性并导致问题。

我用来代替 push() 方法的一些示例是:

  • 这个确实会发回数据,但它会忽略现有列表并为每个数组索引创建一个新的 dataSource 属性。如果我只保存一次,这将起作用,但如果我多次保存网格,那么添加的属性会一直存在并破坏数据完整性。如果保存后可以“重置”数据源(无需重新加载网格),我会接受此选项。

    dataItem["RefItemCategoryServiceIDs[" + i + "]"] = values[i];

  • 这与 .push() 具有相同的效果,它是我在服务器上的对象的属性为 null

    dataItem.RefItemCategoryServiceIDs[i] = values[i];

如果我可以提供更多信息,请告诉我,并提前致谢!

4

1 回答 1

0

我不确定这是处理它的最佳方法,但我对一种可行的方法感到困惑。

我从这里更改了添加到数据项的属性:

for(var x = 0; x < values.length; x++) { //values is array from multiselect
        dataItem.RefItemCategoryServiceIDs.push(values[i]);
}

对此:

for (var i = 0; i < values.length; i++) { //values is array from multiselect
            dataItem["RefItemCategoryServiceIDs[" + i + "]"] = values[i];
}

只是此更改适用于每种情况,除了以下情况:

  1. 使用从多选中选择的 2 个选项保存行,从而将 2 个属性添加到 dataItem。我们会说这些项目的 ID 是 1 和 21。发布的数据如下所示:

    模型[0].RefItemCategoryServiceIDs[0] = 1 模型[0].RefItemCategoryServiceIDs[1] = 21

  2. 保存后,如果我们再次打开该多选并删除第一个选项(ID 为 1 的选项),我们会收到以下数据:

    型号[0].RefItemCategoryServiceIDs[0] = 21 型号[0].RefItemCategoryServiceIDs[1] = 21

这显然是不对的(应该只是 ID 设置为 21 的 1 个条目)。发生这种情况是因为 RefItemCategoryServiceIDs 并不是真正的数组,只是名称看起来像数组条目的属性,以便它们序列化为服务器上的列表(据我所知)。为了缓解这个问题,我在映射当前多选值的代码之前删除了与该数组关联的现有属性:

function CleanDataItemLists(dataItem) {
    if (dataItem.RefItemCategoryCarrierIDs != undefined && dataItem.RefItemCategoryCarrierIDs.length > 0) {
        var i = 0;
        //Continues to remove properties by index until none are left
        while (dataItem.RefItemCategoryCarrierIDs[i] != undefined) {
            delete dataItem["RefItemCategoryCarrierIDs[" + i + "]"];
            i++;
        }
        //Cleans up empty array property
        delete dataItem.RefItemCategoryCarrierIDs;
    }
    return dataItem;
}

调用此函数后,您可以执行上面引用的 for 循环代码,并在存在索引的情况下序列化数据(参见初始帖子,例如序列化数据中缺少索引的示例),允许服务器将其映射到列表对象。就像我说的,我不相信这是最好的方法,但它确实对我有用。希望这可以帮助其他人或导致更好的答案。

于 2013-08-05T18:59:13.223 回答