【问题标题】:Paged TreeList or collapsible hierarchical Grid分页 TreeList 或可折叠分层网格
【发布时间】:2015-04-23 15:29:22
【问题描述】:

我正在考虑使用 Kendo UI Grid。而且看起来功能很齐全。然而,它有一个致命的缺陷。他们的Grid / Hierarchy 只是嵌套网格而不是真正的层次结构。绝对不是递归或分层的层次结构。

幸运的是,他们有一个 TreeList 网格可以做到这一点。但它的功能并不像普通网格那样完整。它实际上缺乏对分页的支持,这使得它完全无法使用:(

我在某处读到他们没有实现分页,因为当扩展父级时,页面将包含一个额外的项目,并且可能超出页面大小。如果你问我,这个论点相当弱......显然它需要按根分页。

这真的很简单。这是一个使用 OData 的示例

OData 示例

GET ~/Products?$filter=ParentId eq null&$expand=Children&$top={pagesize}&$skip={pagenumber}&$count=true

结果

{
    "@odata.count": 33,
    "value": [
        {
            "Id": 1,
            "ParentId": null,
            ...
            "Children": [
                {
                    "Id": 2,
                    "ParentId": 1,
                }
            ]
        },
        ...
    ]
}

完美!换句话说,它不是后端的限制。虽然我可以看到节目过滤可能会变得很棘手。

回到主题。我正在寻找有关如何为 TreeList 实现分页或如何在普通网格中获取可折叠行(递归层次结构样式)的建议。实际上后者会更好,因为它的功能更完整。

【问题讨论】:

    标签: kendo-ui telerik kendo-grid odata hierarchical-data


    【解决方案1】:

    只要你的结构看起来一样,因为父对象有一组子对象,那么你可以在子网格上使用与父网格相同的 detailInit 函数,从而本质上为你提供一个递归分层网格,带有分页在每个网格级别进行过滤。

    这是我做的一个示例。 http://jsbin.com/zosiji/1/edit?html,js,output 我认为就是这样。 父对象有一个 id 和 name 属性,以及一个 Child 数组,它们自始至终都遵循相同的结构。

    【讨论】:

    • 谢谢。但是,过滤和排序仅限于每个子级别。这不是我要找的。​​span>
    【解决方案2】:

    在这里找到一个例子:http://www.telerik.com/forums/does-treelist-support-pagination#5VlH4IMBXEuh819pYvyEvQ

    查看:

    <kendo-treelist k-options="treeListOptions"></kendo-treelist>
    <kendo-pager k-options="pagerOptions"></kendo-pager>
    

    控制器逻辑:

    // default filtering and sorting
    var defaultFilter = { field: "ParentId", operator: "eq", value: null };
    var defaultSort = { field: "Name", dir: "asc" };
    
    var myODataSource = new kendo.data.DataSource({
        type: "odata-v4",
        transport: {
            read: {
                url: "/odata/Products",
                data: {
                    "$expand": "Children($levels=max)"
                }
            }
        },
        pageSize: 15,
        serverPaging: true,
        serverSorting: true,
        serverFiltering: true,
        filter: defaultFilter,
        sort: defaultSort,
        schema: {
            parse: function(response) {
                if (myODataSource.transport.options.read.data.$expand == "Parent($levels=max)") {
                    // if "$expand=Parent($levels=max)" then the hierarchy will be reversed Children -> Parent
                    // thus we need to flatten Parents
                    var ary = _.flattenHierarchy(response.value, 'Parent');
                    // and remove duplicate parents coming from different tree branches
                    response.value = _.uniq(ary);
                } else {
                    // if "$expand=Children($levels=max)" then the hierarchy will be as expected Parent -> Children
                    // thus we need to flatten Children
                    response.value = _.flattenHierarchy(response.value, 'Children');
                }
    
                return response;
            }
        },
        change: function(e) {
            treeListDataSource.read();
        }
    });
    
    // filter hack!
    // http://www.telerik.com/forums/any-filtering-event#--cNXsvF5U6zinsTsyL4eg
    var originalFilterFn = kendo.data.TreeListDataSource.fn.filter;
    kendo.data.TreeListDataSource.fn.filter = function (e) {
        if (arguments.length > 0) {
            if (e === null) {
                // if e is null, then the filter is cleared. So we need to filter by roots to get the normal tree
                myODataSource.transport.options.read.data.$expand = "Children($levels=max)";
                myODataSource.filter(defaultFilter);
            } else {
                // else we're filtering and the result nodes need to include parents to maintain the tree hierarchy
                myODataSource.transport.options.read.data.$expand = "Parent($levels=max)";
                myODataSource.filter(e);
            }
        }
    
        return originalFilterFn.apply(this, arguments);
    };
    
    // sort hack!
    var originalSortFn = kendo.data.TreeListDataSource.fn.sort;
    kendo.data.TreeListDataSource.fn.sort = function (e) {
        if (arguments.length > 0) {
            myODataSource.sort(e);
        }
    
        return originalSortFn.apply(this, arguments);
    };
    
    var treeListDataSource = new kendo.data.TreeListDataSource({
        transport: {
            read: function (options) {
                var data = myODataSource.data().toJSON();
                options.success(data);
            }
        },
        sort: defaultSort,
        schema: {
            model: {
                id: "Id",
                fields: {
                    parentId: { field: "ParentId", type: "number", nullable: true },
                    Id: { field: "Id", type: "number" }
                },
                expanded: true
            }
        }
    });
    
    $scope.treeListOptions = {
        autoBind: false,
        dataSource: treeListDataSource,
        filterable: true, //{ mode: "row"}, not supported (yet) by treelist
        sortable: true,
        resizable: true,
        reorderable: true,
        columns: [
            { field: "Name" },
            { field: "Description" }
        ]
    };
    
    $scope.pagerOptions = {
        autoBind: false,
        dataSource: myODataSource,
        info: true,
        pageSizes: [2, 3, 4, 5, 6],
        refresh: true,
    };
    
    myODataSource.read();
    

    下划线功能

    _.mixin({
        flattenHierarchy: function self(objAry, childPropertyName) {
            // default values
            childPropertyName = typeof childPropertyName !== 'undefined' ? childPropertyName : 'children';
    
            var result = [];
            _.each(objAry, function(obj) {
                // the object it self without children
                var strippedObj = _.omit(obj, childPropertyName);
                result.push(strippedObj);
    
                if (obj.hasOwnProperty(childPropertyName) && obj[childPropertyName] !== null) {
                    // child object(s)
                    var children = obj[childPropertyName];
                    if (!_.isArray(children))
                        children = [children];
    
                    result.pushArray(self(children, childPropertyName));
                }
            });
    
            return result;
        }
    });
    

    【讨论】:

      猜你喜欢
      • 2019-10-15
      • 2010-11-18
      • 1970-01-01
      • 2019-06-15
      • 2018-10-05
      • 2017-12-09
      • 1970-01-01
      • 2019-03-19
      • 1970-01-01
      相关资源
      最近更新 更多