【问题标题】:Refresh a single Kendo grid row刷新单个剑道网格行
【发布时间】:2012-11-16 18:40:08
【问题描述】:

有没有办法在不刷新整个数据源或使用 jQuery 为每个单元格设置值的情况下刷新单个 Kendo 网格行?

【问题讨论】:

    标签: kendo-ui kendo-grid


    【解决方案1】:

    如何定义要更新的行?我将假设这是您选择的行,并且正在更新的列的名称是 symbol

    // Get a reference to the grid
    var grid = $("#my_grid").data("kendoGrid");
    
    // Access the row that is selected
    var select = grid.select();
    // and now the data
    var data = grid.dataItem(select);
    // update the column `symbol` and set its value to `HPQ`
    data.set("symbol", "HPQ");
    

    请记住,DataSource 的内容是一个observable 对象,这意味着您可以使用set 对其进行更新,并且更改应该神奇地反映在grid 中。

    【讨论】:

    • 如果它们是单元格上的自定义模板,不可编辑,并且该模板调用了函数,我们该怎么办。对数据项调用 set 似乎不会重绘模板。
    • @jonperl 我建议您将其作为一个不同的问题提出,以确保我以外的其他人看到它并有机会回答它。无论如何,我用模板尝试过它并且它有效。因此,请发布一些代码,显示您尝试过的内容并显示失败的内容。
    • 注意:“kendoDataGrid”现在被称为“kendoGrid”(或者可能一直是)
    • @OnaBai 当您说“DataSource 的内容是一个可观察的对象”时,这仅适用于您想正确更新整个数据集而不是单行的情况? AFAIK 我需要在更新特定/单行时为每一列调用“data.set”
    • @OnaBai 谢谢。事实证明,如果模型中的列设置为不可编辑(例如model.Fields[0].editable == false,那么如果您在该列上调用data.set('ProductName', 'Cat'),它将不会在网格中更新。我认为这可以修复如果确实需要,可以使用自定义模板
    【解决方案2】:

    data.set 在某些情况下实际上会刷新整个网格并发送databound 事件。这是非常缓慢且不必要的。它还会折叠任何不理想的展开详细信息模板。

    我建议您使用我编写的这个函数来更新剑道网格中的单行。

    // Updates a single row in a kendo grid without firing a databound event.
    // This is needed since otherwise the entire grid will be redrawn.
    function kendoFastRedrawRow(grid, row) {
        var dataItem = grid.dataItem(row);
    
        var rowChildren = $(row).children('td[role="gridcell"]');
    
        for (var i = 0; i < grid.columns.length; i++) {
    
            var column = grid.columns[i];
            var template = column.template;
            var cell = rowChildren.eq(i);
    
            if (template !== undefined) {
                var kendoTemplate = kendo.template(template);
    
                // Render using template
                cell.html(kendoTemplate(dataItem));
            } else {
                var fieldValue = dataItem[column.field];
    
                var format = column.format;
                var values = column.values;
    
                if (values !== undefined && values != null) {
                    // use the text value mappings (for enums)
                    for (var j = 0; j < values.length; j++) {
                        var value = values[j];
                        if (value.value == fieldValue) {
                            cell.html(value.text);
                            break;
                        }
                    }
                } else if (format !== undefined) {
                    // use the format
                    cell.html(kendo.format(format, fieldValue));
                } else {
                    // Just dump the plain old value
                    cell.html(fieldValue);
                }
            }
        }
    }
    

    例子:

    // Get a reference to the grid
    var grid = $("#my_grid").data("kendoGrid");
    
    // Access the row that is selected
    var select = grid.select();
    // and now the data
    var data = grid.dataItem(select);
    
    // Update any values that you want to
    data.symbol = newValue;
    data.symbol2 = newValue2;
    ...
    
    // Redraw only the single row in question which needs updating
    kendoFastRedrawRow(grid, select);
    
    // Then if you want to call your own databound event to do any funky post processing:
    myDataBoundEvent.apply(grid);
    

    【讨论】:

    • 如果您不是在网格本身上进行编辑,而是在弹出窗口中进行编辑,该怎么办。您如何确定正在编辑的行?
    • 我确实得到 myDataBoundEvent 是上面代码 sn-p 中的函数变量。但是什么样的代码实际上进入了那个函数呢?有没有我可以看的活生生的例子?在调用 kendoFastRedrawRow 方法调用后,我目前在最后没有应用调用的情况下有上面的代码,我看到一个旋转的轮子,似乎表明浏览器仍在等待某些东西。有什么指点吗?
    • @Scott 您是否找到了解决方案 - 如何确定弹出窗口中正在编辑的行?
    • 不知道。这是一年多以前的事了。 :)
    • 这种方法在普通网格上效果很好,但是我在另一个网格中包含了使用带有角 1 部分的模板的列,它无法处理这个问题。
    【解决方案3】:

    我找到了一种更新网格数据源并在网格中显示而不刷新所有网格的方法。 例如,您有一个选定的行,并且您想要更改列“名称”的值。

    //the grid
    var grid = $('#myGrid').data('kendoGrid');    
    // Access the row that is selected
    var row = grid.select();
    //gets the dataItem
    var dataItem = grid.dataItem(row);
    //sets the dataItem   
    dataItem.name = 'Joe';
    //generate a new row html
    var rowHtml = grid.rowTemplate(dataItem);
    //replace your old row html with the updated one
    row.replaceWith(rowHtml);
    

    【讨论】:

    • 我不知道他们是否添加了这个功能,因为你写了你的答案,但是如果你用 dataItem.set("Name", "Joe") 替换 dataItem.name 那么你不需要重新渲染网格。它会自行更新。
    • 你的权利它会像其他 Onas 的答案一样更新网格,但它会重新渲染整个网格,如果你有过滤器,它将隐藏该行或将其移动到其他位置(排序)。
    【解决方案4】:
    updateRecord(record) {
        const grid = $(this.el.nativeElement).data('kendoGrid');
        const row = grid.select();
        const dataItem = grid.dataItem(row);
        for (const property in record) {
          if (record.hasOwnProperty(property)) {
            dataItem.set(property, record[property]);
          }
        }
      }
    

    【讨论】:

    • 对此添加一些描述,它会更好地被接收。看起来很不错的代码。
    猜你喜欢
    • 1970-01-01
    • 2015-05-07
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2013-08-26
    • 2015-10-18
    • 1970-01-01
    相关资源
    最近更新 更多