刷新单个Kendo表格行

42

有没有方法可以刷新Kendo表格中的单个行而不刷新整个数据源或使用jQuery为每个单元格设置值?

4个回答

58

你如何定义要更新的行?我会假设它是你选择的那一行,被更新的列的名称是 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自动反映出来


4
如果单元格上有自定义模板且不可编辑,而该模板调用了一个函数,那么我们应该怎么做?调用数据项的set方法似乎不能重新绘制模板。 - jonperl
@jonperl 我建议你将其作为不同的问题提出,以确保其他人看到并有机会回答。无论如何,我尝试使用模板并且它有效。因此,请发布一些代码,显示您尝试过什么以及失败的地方。 - OnaBai
@Simon_Weaver,你是对的!但这也适用于任何_可观察_对象。_Observable_并不是JavaScript语言中内置的东西,拦截对象的更改的唯一方法是使用某些方法来检查何时分配值以及谁希望了解它(用户界面)。 - OnaBai
4
@OnaBai 谢谢。同时,结果证明,如果在模型中将某一列设置为不可编辑(例如model.Fields[0].editable == false),那么如果在该列上调用data.set('ProductName', 'Cat'),则这列在网格中不会更新。我认为如果确实需要,可以通过自定义模板来解决这个问题。 - Simon_Weaver
我已经尝试了@OnaBai和Adam Yaxley的解决方案。 OnaBai的解决方案一开始可以工作,但最终会出现各种滚动和当前行和单元格选择问题。 Adam的解决方案完美地工作,没有任何副作用。 - stricq
显示剩余4条评论

34

data.set 有时会刷新整个网格并触发一个 databound 事件,这非常缓慢且不必要。它还会折叠任何已展开的详细模板,这并不理想。

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

// 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);

3
如果您不是直接在网格上进行编辑,而是通过弹出窗口进行编辑,那么如何确定正在编辑的行? - Scott
不知道。这是一年多以前的事情了。 :) - Scott
@Adam Yaxley,这对我来说很好用,但是有没有办法使用json刷新行中的所有列,而不是像data.symbol = newValue那样每个列都要做一遍呢?因为我的网格包含多达60列。 - Gurunadh
1
这种方法在普通网格中效果很好,但是另一个网格包含了使用 Angular 1 部件的模板列,它无法处理。 - user2590928
这是一个非常有趣的输入,我进行了测试。它对很多事情都有效。但在我的情况下,使用分组和聚合求和时,在数据绑定上它不起作用。感谢您的输入。我的测试链接:https://dojo.telerik.com/ikiDIZIY - Severin
显示剩余4条评论

9
我找到了一种方法,可以更新网格(grid)的数据源并在不刷新整个网格的情况下显示出来。 例如,您选择了一行并想要更改“名称”列的值。
//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,那么你就不需要重新渲染网格。它会自动更新。 - John Lord
没错,它会像其他 Onas 的答案一样更新网格,但它将重新渲染整个网格,如果你有筛选,它将隐藏行或将其移动到其他位置(按排序)。 - Srulik
完美!我随后添加了以下代码行以重新选择先前选择的行:grid.select(grid.table.find("[data-uid=" + dataItem.uid + "]")); - Randy Burden

2
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]);
      }
    }
  }

在编程方面的相关内容进行翻译,返回已翻译的文本:为此添加一些描述将更容易接受。这看起来是非常好的代码。 - John Lord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接