在 Kendo UI 网格中控制组顺序

Posted

技术标签:

【中文标题】在 Kendo UI 网格中控制组顺序【英文标题】:Controlling Group order in a Kendo UI Grid 【发布时间】:2013-04-28 07:15:03 【问题描述】:

有没有办法控制 Kendo UI 网格中的分组顺序。有一个组我想在所有其他组之前去,但似乎 Kendo UI 网格按字母顺序对组进行排序。我知道在分组名称中添加一个空格是可行的,但这似乎很老套。

谢谢 狮子座

【问题讨论】:

感谢关于在名称前面添加空格(从后端)的提示 - 当它在 UI 中呈现时,空格实际上已被删除 【参考方案1】:

目前无法根据组字段以外的其他内容对分组进行排序。有一种方法可以像 Telerik 在他们的非剑道网格中对组进行排序是我现在对他们最大的功能要求。所以我们现在只能使用 hack。

对我有用的一个技巧是将排序字段和显示字段组合成一个新的字符串列,该列将排序字段部分隐藏在隐藏的跨度内。这是在数据源端完成的(对我来说,在 SQL 中)。即使排序字段是数字,新列也会被排序为字符串,因此在某些情况下您必须适当地填充。

例如,如果我的数据是:

[ 
     
      'Name': 'Alice', 
      'Rank': 10, 
      'RankName': '<span class="myHiddenClass">10</span>Alice', 
      ... (other fields)
    ,  
     
      'Name': 'Bob', 
      'Rank': 9, 
      'RankName': '<span class="myHiddenClass">09</span>Bob', 
      ... (other fields)
    ,  
     
      'Name': 'Eve', 
      'Rank': 11, 
      'RankName': '<span class="myHiddenClass">11</span>Eve', 
      ... (other fields)
     
    ... (Multiple Alice / Bob / Eve records)
]

然后我可以按 RankName 字段而不是 Name 字段进行分组。它将在组标题中显示名称字段,但按排名字段排序。在这种情况下,即使 Alice 按字母顺序排在第一位,Bob 也会显示为第一组。这与您提到的空格填充类似。

【讨论】:

【参考方案2】:

尝试 AddDescendingAddAscending,请参阅下面的示例

@(html.Kendo().Chart<T>()
[... other code ...]
.DataSource(ds => ds
    .Read(read => read.Action("action", "controller"))
    .Group(g => g.AddDescending(model=> model.property)) // <-- subtle difference here!
)
[... other code ...]
)

http://www.telerik.com/forums/stacked-chart-legend-order

【讨论】:

我能够将排序顺序应用到 Kendo Grid。 AddDescendingAddAscending 工作正常,没有任何问题【参考方案3】:

Kendo 的分组按给定字段(例如fooBar)对数组中的所有元素进行排序,然后迭代排序的元素。简而言之,用伪代码:

if (element[i].fooBar!= element[i-1].fooBar)  
    StartNewGroup(element[i]);
 else 
    AddToLastGroup(element[i]);

由于需要排序后的数组进行分组,因此更改排序很棘手。我创建了代码来覆盖内部 groupBy() 函数,它允许我按照我喜欢的方式对分组结果进行排序:

function overrideKendoGroupBy() 
    var origFunc = kendo.data.Query.prototype.groupBy;
    kendo.data.Query.prototype.groupBy = function (descriptor) 
        var q = origFunc.call(this, descriptor);

        var data = SortYourData(q.data, descriptor.dir);

        return new kendo.data.Query(data);
    ;

在页面加载后的某个时间致电overrideKendoGroupBy()。现在只需实现一个SortYourData() 函数,其中q.data 是一个分组数组,descriptor.dir"asc""desc"q.data[n] 有一个 items 数组,其中包含来自原始数据源的元素,这些元素包含在 nth 分组中。

注意:此解决方案仅在您不使用分页时才有效。在应用分组之前页面已被分解,因此如果您的数据跨越多个页面,所有的赌注都将失败。

【讨论】:

【参考方案4】:

以下代码会将满足if 条件的组推到网格底部

group: 
    dir: "asc",
    field: "FieldToGroupBy",
    compare: function (a, b) 
        if (b.value == "GROUP_TO_SHOW_LAST") 
            return -1; // this will push the group to bottom
        
    
,

如果你想对组进行比较,你应该使用ab,然后相应地设置返回值。 您需要根据自己的要求使用 返回值

注意:返回值应该是0、1、-1中的任何一个

【讨论】:

【参考方案5】:

网格支持分组时的自定义排序方向 - 当没有分组时,组的排序方式与列的排序方式(使用客户端排序时)相同。排序方向与 javascript 中的默认排序相同。

【讨论】:

【参考方案6】:

您可以在定义数据源后添加查询,这似乎可行

 related.query(
        sort:  field: "Sort", dir: "asc",
        group:  field: "CategoryName" ,
        pageSize: 50
    );

相关的是数据源的名称

【讨论】:

【参考方案7】:

一个老问题,但我也遇到了同样的问题

理论上你可以按照这里的建议:https://github.com/telerik/kendo-ui-core/issues/4024

$("#grid").kendoGrid(
    ...
    groupable: 
        sort: 
            dir: "asc",
            compare: function compareByTotal(a, b) 
                if (a.items.length === b.items.length) 
                    return 0;
                 else if (a.items.length > b.items.length) 
                    return 1;
                 else 
                    return -1;
                
            
        
    

但是这对我不起作用。

对我有用的是……

向你的数据源添加一个额外的列,所以现在你有

GroupByName 按顺序分组

在你的架构中做

dataSource = 
                data: dataProperties,
                schema: 
                    model: 
                        fields: 
                            groupByName: 
                                type: "string",
                                from: "dataPropertyDefinition.GroupName"
                            ,
                            groupOrderBy: 
                                type: "string",
                                from: "dataPropertyDefinition.groupOrderBy"
                            
                        
                    
                ,
                group: 
                    field: "groupOrderBy",
                
            ;

所以现在您按 groupOrderBy 排序,可以是任何您喜欢的,并且您使用 groupHeaderTemplate 来显示名称

        const columns: Array<object> = [
            
                field: "groupOrderBy",
                hidden: true,
                groupHeaderTemplate: function (x: any)
                
                    return x.items[0].groupByName;
                
            

【讨论】:

【参考方案8】:

这是一个简单的解决方法。不漂亮但足够简单......

只需在文本前添加空格即可实现理想的排序

   [ 
      'Value': 1, 
      'Description': 'Description 1', 
      'Grouping': 'Group 1'
    ,  
     
      'Value': 2, 
      'Description': 'Description 2', 
      'Grouping': ' Group 2'
    ,
     
      'Value': 3, 
      'Description': 'Description 3', 
      'Grouping': 'Group 3'
    ] 

在上面的示例代码中,Group 2 出现在 Group 1 之前,因为有一个前导空格。

【讨论】:

【参考方案9】:

一旦你有你的数据,使用列来指定列的顺序,例如

columns: [

field: "LastName",
title: "Last Name" 
,

field: "FirstName",
title: "First Name"

]

【讨论】:

以上是关于在 Kendo UI 网格中控制组顺序的主要内容,如果未能解决你的问题,请参考以下文章

具有级联下拉列表的 Kendo UI 网格

如何将模型用作 Kendo UI 网格的数据源?

如何使用 Kendo 网格在控制器中显示验证错误消息?

Kendo UI Grid 内联编辑发布的数据为空

用于 jquery CRUD 的 Asp.net core mvc + kendo ui

kendo ui AngularJS Grid CRUD操作