如何防止重新绑定 kendo 网格数据项更改?

How to prevent rebind on kendo grid data item change?

我有一个 kendo 网格,当一个项目被选中时,我想修改底层数据项,所以我正在这样做...

selectionChange: function(e)
    {
        var component = $(this.table).closest('.component');
        var grid = this;
        var val = !component.hasClass("secondary");

        var selection = grid.dataItems(grid.select());
        selection.forEach(function () {
            this.set("SaleSelected", val);
        });
    }

我还有 2 个按钮,可以让我在 2 个网格之间推动项目...

select: function (e) {
            e.preventDefault();
            var sender = this;

            // get kendo data source for the primary grid
            var source = $(sender).closest(".component")
                .find(".component.primary")
                .find(".details > [data-role=grid]")
                .data("kendoGrid")
                .dataSource;

            // sync and reload the primary grid
            source.sync()
                .done(function () {
                    source.read();
                    my.Invoice.reloadGridData($(sender).closest(".component").find(".component.secondary").find(".details > [data-role=grid]"));
                });

            return false;
        },
        deselect: function (e) {
            e.preventDefault();
            var sender = this;
            debugger;
            // get kendo data source for the secondary grid
            var source = $(sender).closest(".component")
                .find(".component.secondary")
                .find(".details > [data-role=grid]")
                .data("kendoGrid")
                .dataSource;

            // sync and reload the primary grid
            source.sync()
                .done(function () {
                    source.read();
                    my.Invoice.reloadGridData($(sender).closest(".component").find(".component.primary").find(".details > [data-role=grid]"));
                });

            return false;
        }

基本上可以在服务器上将 grid1 中的 "selected items" 标记为这样,然后重新加载网格以移动项目。

我认为一切都很好,但显然 Kendo 有其他想法。

编辑数据项会导致其所属的网格重新绑定,从而丢失选择状态,从而导致用户出现一些令人困惑的行为。

有没有办法告诉kendo"i'm going to edit this unbound property right now, don't go messing with binding"?

我认为您可以将 dataBinding 事件绑定到一个 "preventDefault",然后在空闲时解除绑定并刷新

var g = $("#myGrid").data("kendoGrid");

g.bind("dataBinding", function(e) { e.preventDefault(); });

然后……

g.unbind("dataBinding");

好吧,事实证明 kendo 有点古怪,我仍然不明白为什么他们坚持要你调用他们所有的 "api stuff" 来完成简单的任务,而更直接地做事实际上效果更好.

在我的例子中,我完全删除了选择更改调用并让 kendo 处理它,然后在我的选择按钮处理程序中移动网格之间的数据我直接更新数据项的属性而不是调用 "item.set("prop", value)" 我现在必须做 "item.prop = value".

最终结果是这样的...

select: function (e) {
            e.preventDefault();
            var sender = this;

            // get some useful bits
            var component = $(sender).closest(".component");
            var primaryGrid = component.find(".component.primary").find(".details > [data-role=grid]").data("kendoGrid");

            // get the new selection, and mark the items with val
            var selection = $(primaryGrid.tbody).find('tr.k-state-selected');

            selection.each(function (i, row) {
                primaryGrid.dataItem(row).SaleSelected = true;
                primaryGrid.dataItem(row).dirty = true;
            });

            // sync and reload the primary grid
            primaryGrid.dataSource.sync()
                .done(function () {
                    primaryGrid.dataSource.read();
                    component.find(".component.secondary")
                        .find(".details > [data-role=grid]")
                        .data("kendoGrid")
                        .dataSource
                        .read();
                });

            return false;
        },
        deselect: function (e) {
            e.preventDefault();
            var sender = this;

            // get some useful bits
            var component = $(sender).closest(".component");
            var secondaryGrid = component.find(".component.secondary").find(".details > [data-role=grid]").data("kendoGrid");

            // get the new selection, and mark the items with val
            var selection = $(secondaryGrid.tbody).find('tr.k-state-selected');

            selection.each(function (i, row) {
                secondaryGrid.dataItem(row).SaleSelected = false;
                secondaryGrid.dataItem(row).dirty = true;
            });

            // sync and reload the primary grid
            secondaryGrid.dataSource.sync()
                .done(function () {
                    secondaryGrid.dataSource.read();
                    component.find(".component.primary")
                        .find(".details > [data-role=grid]")
                        .data("kendoGrid")
                        .dataSource
                        .read();
                });

            return false;
        }

kendo 似乎将对 item.set(p, v) 的任何调用作为重新加载数据的触发器,因此避免使用 kendo 包装器并直接转到项目属性允许我直接控制进程。

将代码从选择更改事件处理程序移动到按钮单击处理程序也意味着我只关心数据在实际需要发送到服务器时是否正确,我只需要注意这一点。

我不喜欢这样,但它相当干净,即使基础数据不正确,ui 也能显示正确的图片。

我的另一个选择是创建自定义绑定,但考虑到绑定必须根据绑定到主网格或辅助网格的天气产生不同的结果,我怀疑这会是很多 js 代码,这感觉就像两害相权取其轻。