Ленивая загрузка в Kendo UI treeview с кэшированием

Я использую Kendo UI TreeView для загрузки иерархических данных на моей веб-странице. По умолчанию я загружаю данные до 3 уровней (т. е. Root -> Root directs -> Root directs' directs). Мне нужен способ лениво загружать оставшиеся узлы, когда пользователь расширяется дальше по дереву. Кроме того, уже извлеченные данные должны кэшироваться локально, чтобы избежать ненужных вызовов для уже развернутых узлов. Я новичок в Kendo UI и не имею достаточно времени, чтобы пройти документацию. В JSON выглядит как

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

может ли кто-нибудь указать на образцы кода ? Сколько из вышеперечисленного поддерживается из коробки Kendo ?

спасибо заранее.

2 ответов


эта функциональность не поддерживается конфигурацией out of the box, но может быть достигнута с помощью пользовательского транспорта. Вот как создать гибридные источники данных, которые работают с 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>

после еще немного работы, я получил это, чтобы работать. Я все еще не уверен, зачем нужна переменная localData, так как Kendo treeview, похоже, не использует ее, когда узел уже там. Вот мой абы решение:

<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>

Я использую хранимую процедуру для чтения значений из 3 таблиц в объект дерева. Вот код для объекта дерева:

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; }
}

и моя хранимая процедура:

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

AS НАЧИНАТЬ УСТАНОВИТЬ ПАРАМЕТР NOCOUNT На;

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

конец