Telerik Kendo UI 网格:分组和排序在 grid.refresh() 中仍然存在,但折叠的组得到扩展;如何保存状态 [英] Telerik Kendo UI grid: grouping and sorting survive grid.refresh() but collapsed groups get expanded; how to preserve state

查看:36
本文介绍了Telerik Kendo UI 网格:分组和排序在 grid.refresh() 中仍然存在,但折叠的组得到扩展;如何保存状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与监视动态变化数据的仪表板"应用程序中的网格一样,我的 (Telerik) Kendo UI 网格每隔 60 秒定期刷新一次新数据:

As is typical for grids in a "dashboard" application that monitors dynamically changing data, my (Telerik) Kendo UI grid is refreshed with fresh data periodically, every 60 seconds:

grid.dataSource.data(freshData);
grid.refresh();  // have been informed this refresh may not be necessary

架构没有改变,但一些新行可能会出现在数据集中,而一些新行可能已被删除.

The schema does not change, but some new rows might show up in the dataset and some might have been removed.

虽然 grid.refresh() 保持分组不变,并且排序状态也被保留,但任何折叠的组都会展开.

Although the grid.refresh() leaves the groupings intact, and the sort state is also preserved, any collapsed groups get expanded.

问题:如何保留(或恢复)组的展开/折叠状态(因此,专注于特定展开组而其他组折叠的用户不会因每个组都重新获得定期更新而感到不便/沮丧-默认扩展)?

QUESTION: How to preserve (or restore) the expanded/collapsed state of the groups (so a user focusing on a particular expanded group with the other groups collapsed is not inconvenienced/frustrated by the periodic updates in which every group gets re-expanded by default)?

一些 Winforms 网格提供了一种在刷新数据之前对组展开/折叠状态拍摄快照"的方法,然后在数据源刷新后重新应用该状态.如果 Kendo UI 网格中的组标题行有 UID(在刷新后仍然存在),则可以这样做.但请参阅下面不涉及持久 UID 的建议方法.

Some Winforms grids provide a way to "take a snapshot" of the group expand/collapse state before refreshing data, and then to reapply that state after the datasource refresh. If the group header rows in the Kendo UI grid had UIDs (that survived a refresh) it could be done. But see the suggested approach below that does not involve persistent UIDs.

用例:这是此功能的一个典型但有些戏剧性的用例.疾病控制中心正在按城市实时监测特定流感病毒的爆发情况.每 15 秒刷新一次数据集.他们碰巧现在专注于洛杉矶,并扩大了那个城市,而其他城市则倒塌了.如果整个网格每 15 秒膨胀一次,就会激怒 CDC 的医生,他们进去勒死程序员,然后回家打高尔夫球,洛杉矶的每个人都屈服了.剑道真的要为那场灾难负责吗?

USE CASE: Here is a typical if somewhat dramatic use case for this feature. Center for Disease Control is monitoring real-time outbreaks of a particular strain of flu, by city. Every 15 seconds the dataset is being refreshed. They happen to be focusing at the moment on Los Angeles and have that city expanded, and the other cities collapsed. If every 15 seconds the entire grid expands, it pisses off the doctors at the CDC and they go in and strangle the programmer and then they go home to play golf, and everyone in Los Angeles succumbs. Does Kendo really want to be responsible for that disaster?

可能的功能增强建议:忽略我上面关于 UID 的建议.这是一个更好的方法.网格有

POSSIBLE FEATURE ENHANCEMENT SUGGESTION: Ignore my suggestion about a UID above. Here's a better way. The grid has

<div class="k-group-indicator" data-field="{groupedByDataFieldName}">
    ...
</div>

现在,如果 k-group-indicator div 可以包含 data-field 的不同值的列表,每个键的关联数据是相应部分的展开/折叠状态,它会然后可以在调用 dataSource.data(someNewData) 方法之前将该列表保存到缓冲区,然后在侦听 dataBound 事件的事件处理程序中,可以重新应用这些展开状态.要为分组值找到相应的分组部分,如果 k-grouping-row 可以有一个名为 group-data-value 的属性来保存特定分组部分的分组值,例如销售"或市场营销",如果按名为部门"的数据字段分组.

Now, if that k-group-indicator div could contain a list of the distinct values of data-field with each key's associated data being the expanded/collapsed state of the corresponding section, it would then be possible to save that list to a buffer before making a call to the dataSource.data( someNewData) method, and then in the eventhandler listening for dataBound event, those expand states could be reapplied. To find the corresponding grouping section for the grouping value, it would be very helpful if the k-grouping-row could have a property called group-data-value which held the grouping value of the particular grouping section, e.g. "Sales" or "Marketing" if one were grouping by a data-field called Department.

<div class="k-group-indicator" data-field="dept" data-title="Dept" data-dir="asc">
       ...
   <div class="k-group-distinct-values">
     <div group-data-value="Sales" aria-expanded="false" />
     <div group-data-value="Events Planning" aria-expanded="true" />
   </div>  
</div>

然后在k-grouping-row中:<tr class="k-grouping-row" group-data-value="Sales">

推荐答案

这不是内置功能是可以理解的.这非常复杂,因为如果您有嵌套分组,您必须记住它所在的层次结构中的每个折叠组.由于项目将移入和移出 DataSource,因此跟踪起来会很痛苦.

It is understandable that this isn't a built-in feature. It is pretty complicated because if you have nested groupings, you would have to remember each collapsed group in the hierarchy that it existed in. Since items will be moving in and out of the DataSource, this would be a pain to track.

也就是说,只要您不要变得太复杂,这是一种非常老套的方法来完成您想要的事情.它只是使用 groupHeaderTemplate 属性为每个分组行添加一个 UID.我只是使用列名 + 值作为 UID,如果您进入多个分组,这在技术上是错误的,但作为示例已经足够了.

That said, here is a very hackish way to accomplish what you want, as long as you don't get too complicated. It just uses the groupHeaderTemplate property to add a UID to each grouping row. I am just using the column name + value as the UID, which is technically wrong if you get into multiple groupings, but it is good enough for an example.

从那里,在您刷新之前,您可以从 Kendo 现在拥有的 ARIA 属性中找到折叠的组(旁注,您必须使用 2012 Q3 才能工作).然后向下钻取,获取模板添加的 UID.

From there, before you refresh you can find the collapsed groups from the ARIA attribute that Kendo has now (side-note, you have to be using 2012 Q3 for this to work). Then drill down and get the UID that was added by the template.

刷新后,您可以找到具有匹配 UID 的行并将它们传递给网格的 .collapseGroup() 函数以重新折叠它.

After the refresh, you can find the rows with a matching UID and pass them to the grid's .collapseGroup() function to re-collapse it.

这里有一个可以演示的 jsFiddle.

还有来自jsFiddle的代码复制/粘贴在中(请注意我只在City列上设置了模板,所以在这个例子中只有City列会保留分组折叠!):

And the code from the jsFiddle copy/pasted in (please note that I only set the template on the City column, so only the City column will preserve grouping collapse in this example!):

HTML:

<button id="refresh">Refresh</button>
<div id="grid" style="height: 380px"></div>

JavaScript:

JavaScript:

var _getCollapsedUids = function () {
    var collapsedUids = [];
    $("#grid .k-grouping-row span[data-uid]")
        .each(function(idx, item) {
            if($(item)
               .closest(".k-grouping-row")
               .children("td:first")
               .attr("aria-expanded") === "false") {
                collapsedUids.push($(item).data("uid"));
            }
        }
    );
    return collapsedUids;
};

var _collapseUids = function (grid, collapsedUids) {
    $("#grid .k-grouping-row span[data-uid]")
        .each(function(idx, item) {
            if($.inArray($(item).data("uid"), collapsedUids) >= 0) {
                console.log("collapse: " + $(item).data("uid"))
                grid.collapseGroup($(item).closest("tr"));
            }
        }
    );
};

var refresh = function () {
    var collapsedUids = _getCollapsedUids();
    var grid = $("#grid").data().kendoGrid;
    grid.dataSource.data(createRandomData(50));
    _collapseUids(grid, collapsedUids);
};

$("#refresh").click(refresh);

$("#grid").kendoGrid({
    dataSource: {
        data: createRandomData(50),
        pageSize: 10
    },
    groupable: true,
    sortable: true,
    pageable: {
        refresh: true,
        pageSizes: true
    },
    columns: [ {
            field: "FirstName",
            width: 90,
            title: "First Name"
        } , {
            field: "LastName",
            width: 90,
            title: "Last Name"
        } , {
            width: 100,
            field: "City",
            groupHeaderTemplate: '<span data-uid="City-#=value#">#= value #</span>'
        } , {
            field: "Title"
        } , {
            field: "BirthDate",
            title: "Birth Date",
            template: '#= kendo.toString(BirthDate,"dd MMMM yyyy") #'
        } , {
            width: 50,
            field: "Age"
        }
    ]
});

<小时>

就我个人而言,我根本不喜欢这种解决方案.这太 hacky 并且太多 DOM 遍历.但是,如果不重新实现网格小部件,我想不出更好的方法来做到这一点.也许它对于你想要完成的事情或者给你一个更好的想法已经足够了.


Personally I don't really like this solution at all. It is way too hacky and way too much DOM traversal. However without re-implementing the grid widget I can't think of a better way to do it. Maybe it will be good enough for what you are trying to accomplish or give you a better idea.

最后一个音符;我检查了 Kendo UI 源代码,它似乎没有跟踪哪些分组被展开/折叠.他们做的事情类似于我对 aria 属性所做的事情,但检查的是驱动图标状态的类:

One last note; I checked the Kendo UI source code and it does not appear to track which groupings are expanded/collapsed. They do something similar to what I did with the aria attribute, but instead check the class that drives the icon state:

            if(element.hasClass('k-i-collapse')) {
                that.collapseGroup(group);
            } else {
                that.expandGroup(group);
            }

如果您没有使用 Kendo 2012 Q3 并且不能使用 aria-expanded 属性,您可以更改代码以检查图标类.

If you are not using Kendo 2012 Q3 and can't use the aria-expanded attribute, you could change the code to check the icon class instead.

这篇关于Telerik Kendo UI 网格:分组和排序在 grid.refresh() 中仍然存在,但折叠的组得到扩展;如何保存状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆