简体   繁体   English

使用缓存在Kendo UI树视图中加载延迟

[英]Lazy load in Kendo UI treeview with caching

I am using Kendo UI TreeView to load hierarchical data in my webpage. 我正在使用Kendo UI TreeView在我的网页中加载分层数据。 By default, I am loading data upto 3 levels (ie Root -> Root directs -> Root directs' directs). 默认情况下,我将数据加载到3个级别(即Root - > Root指示 - > Root指示'指示)。 I need a way to lazily load the remaining nodes as user expands further down the tree. 当用户进一步向下扩展树时,我需要一种方法来延迟加载剩余的节点。 Also, the already fetched data must be cached locally to avoid unnecessary calls for already expanded nodes. 此外,必须在本地缓存已获取的数据,以避免对已扩展的节点进行不必要的调用。 I am new to Kendo UI and do not have enough time to go through documentation. 我是Kendo UI的新手,没有足够的时间来阅读文档。 The json looks like json看起来像

   {
      Id: '1',
      ParentId: '-1',
      Payload: {... }
      Children: [
          Id: '2',
          ParentId: '1',
          PayLoad: {...},
          Children: [{...}]
          ]
            ....
    }

Can someone point out to code samples ? 有人可以指出代码示例吗? How much of the above is supported out of box by Kendo ? Kendo支持多少以上的支持?

Thanks in advance. 提前致谢。

That functionality is not supported by the out of the box configuration, but can be achieved through a custom transport. 开箱即用的配置不支持该功能,但可以通过自定义传输实现。 Here's how to create hybrid data sources that work with the localData array if the items are available, and otherwise perform requests to the server. 以下是如果项目可用,如何创建与localData数组一起使用的混合数据源,以及如何向服务器执行请求。

 var localData = [ { id: 1, text: "Node 1", hasChildren: true, items: [ { id: 101, text: "Node 1.1", hasChildren: true, items: [ { id: 10101, text: "Node 1.1.1" } ] } ] }, { id: 2, hasChildren: true, text: "Node 2" }, { id: 3, hasChildren: true, text: "Node 3" } ]; function get(data, id) { if (!id) { return data; } else { for (var i = 0; i < data.length; i++) { if (data[i].id == id) { return data[i].items; } else if (data[i].items) { var result = get(data[i].items, id); if (result) return result; } } } } var homogeneous = new kendo.data.HierarchicalDataSource({ transport: { read: function (options) { var id = options.data.id; var data = get(localData, id); if (data) { options.success(data); } else { // mock call to server with static data // you can use $.ajax() and call options.success(data) on success setTimeout(function() { options.success([ { id: id + 1, text: "Remote node 1", hasChildren: false }, { id: id + 2, text: "Remote node 2", hasChildren: true } ]); }, 1000); } } }, schema: { model: { id: "id" } } }); $("#tree").kendoTreeView({ dataSource: homogeneous }); 
 <link href="http://cdn.kendostatic.com/2013.1.319/styles/kendo.common.min.css" rel="stylesheet" /> <link href="http://cdn.kendostatic.com/2013.1.319/styles/kendo.default.min.css" rel="stylesheet" /> <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <script src="http://cdn.kendostatic.com/2013.1.319/js/kendo.web.min.js"></script> <div id="tree"></div> 

After some more work, I got this to work. 经过一些工作,我得到了这个工作。 I'm still not sure why the localData variable is needed, since the Kendo treeview doesn't seem to use it once a node is already in there. 我仍然不确定为什么需要localData变量,因为一旦节点已经在那里,Kendo树视图似乎不会使用它。 Here's my solution anyhow: 无论如何,这是我的解决方案:

<div id="treeview"> </div>

<script>
    var serviceRoot = "http://<local name>:58754/api/";

    var localData;

    $(document).ready(function () {        

        var homogeneous = new kendo.data.HierarchicalDataSource({
            transport: {
                read: function (options) {
                    if (typeof options.data.ID != 'undefined') {
                        var id = options.data.ID;
                        var data = getNextLevel(localData, id);
                        if (data) {
                            options.success(data);
                        } else {
                            var currentnode = get(localData, id);
                            if (currentnode.Level == 1) {
                                $.ajax({
                                    url: serviceRoot + "tree",
                                    data: 'ID=' + currentnode.ID + '&Level=' + currentnode.Level,
                                    type: "Get",
                                    success: function (result) {
                                        setTimeout(function () {
                                            var res = result;
                                            addToLocalData(localData, res, currentnode.ID);
                                            options.success(res);
                                        }, 1000);

                                    },
                                    error: function (result) {
                                        options.error(result);
                                    }
                                });
                            } else {
                                if (currentnode.Level == 2) {
                                    $.ajax({
                                        url: serviceRoot + "tree",
                                        data: 'ID=' + currentnode.ID + '&Level=' + currentnode.Level,
                                        type: "Get",
                                        success: function (result) {
                                            setTimeout(function () {
                                                var res = result;
                                                addToLocalData(localData, res, currentnode.ID);
                                                options.success(res);
                                            }, 1000);                                            
                                        },
                                        error: function (result) {
                                            options.error(result);
                                        }
                                    });
                                }
                            }
                        }
                    }
                    else {
                        $.ajax({
                            url: serviceRoot + "tree",
                            data: 'ID='+ null +'&Level='+ null,
                            type: "Get",
                            success: function (result) {
                                setTimeout(function () {
                                    options.success(result);
                                }, 1000);
                                localData = result;
                            },
                            error: function (result) {
                                options.error(result);
                            }
                        });
                    }
                }
            },
            schema: {
                model: {
                    id: "ID",
                    hasChildren: "HasChildren"
                }
            }
        });
        $("#treeview").kendoTreeView({
            dataSource: homogeneous,
            dataTextField: "Name"
        });
    });    

    //Checks if nodes are already in the tree and returns it if it does
    function getNextLevel(data, id) {
        if (!id) {
            return data;
        } else {
            for (var i = 0; i < data.length; i++) {
                if (data[i].ID == id) {
                    return data[i].Items;
                } else if (data[i].Items) {
                    for (var j = 0; j < data[i].Items.length; j++) {
                        if (data[i].Items[j].ID == id) {
                            return data[i].Items[j].Items;
                        }
                    }
                }
            }
        }
    }

    //Get Tree object for a given ID
    function get(data, id) {
        if (id) {
            for (var i = 0; i < data.length; i++) {
                if (data[i].ID == id) {
                    return data[i];
                }
                else if (data[i].Items) {
                    for (var j = 0; j < data[i].Items.length; j++) {
                        if (data[i].Items[j].ID == id) {
                            return data[i].Items[j];
                        }
                    }
                }
            }
        }
        return null;
    }

    //Add newly read nodes to cached tree
    function addToLocalData(localdata, data, id) {
        if (!id) {
            return localdata;
        } else {
            for (var i = 0; i < localdata.length; i++) {
                if (localdata[i].ID == id) {
                    localdata[i].Items = data;
                    return;
                } else {
                    if (localdata[i].Items) {
                        for (var j = 0; j < localdata[i].Items.length; j++) {
                            if (localdata[i].Items[j].ID == id) {
                                localdata[i].Items[j].Items = data;
                                return;
                            }
                        }
                    }
                }
            }
        }
    }

</script>

I'm using a stored procedure to read values from 3 tables into a Tree object. 我正在使用存储过程将3个表中的值读入Tree对象。 Here is the code for the Tree object: 这是Tree对象的代码:

public class Tree
{
    public Guid ID { get; set; }
    public string Name { get; set; }
    public bool HasChildren { get; set; }
    public int Level { get; set; }
    public IEnumerable<Tree> Items { get; set; }
}

And my Stored procedure: 我的存储过程:

ALTER PROCEDURE [dbo].[GetTreeItems] 
@ID uniqueidentifier, @CurrentLevel int

AS BEGIN SET NOCOUNT ON; 开始设置NOCOUNT ON;

if @CurrentLevel is null
    select IDStation as ID, StationName as Name, null as IDParent, 1 as [Level] ,
    case when (select COUNT(*) from Unit where Unit.IDStation = Station.IDStation) > 0 then 1 else 0 end as HasChildren
    from Station
    order by [Level], Name
--union

else if @CurrentLevel = 1
    select IDUnit as ID, UnitName as Name, Station.IDStation as IDParent, 2 as [Level], 
    case when (select COUNT(*) from Component where Component.IDUnit = Unit.IDUnit) > 0 then 1 else 0 end as HasChildren
    from Unit inner join Station on Station.IDStation = Unit.IDStation
    where Station.IDStation = @ID
    order by [Level], Name
--union 

if @CurrentLevel = 2
    select IDComponent as ID, ComponentName as Name, Unit.IDUnit as IDParent, 
    3 as [Level], 0 as HasChildren
    from Component inner join Unit on unit.IDUnit = Component.IDUnit
    where Unit.IDUnit = @ID
    order by [Level], Name

END 结束

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM