2013-12-09 4 views
6

Ich benutze Kendo UI TreeView, um hierarchische Daten auf meiner Webseite zu laden. Standardmäßig lade ich Daten auf bis zu 3 Ebenen (zB Root -> Root directs -> Root directs 'directs). Ich brauche einen Weg, um die verbleibenden Knoten faul zu laden, wenn der Benutzer weiter unten im Baum expandiert. Außerdem müssen die bereits abgerufenen Daten lokal zwischengespeichert werden, um unnötige Aufrufe für bereits erweiterte Knoten zu vermeiden. Ich bin neu in Kendo UI und habe nicht genug Zeit, um durch die Dokumentation zu gehen. Der JSON sieht aus wieLazy laden in Kendo UI Treeview mit Caching

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

Kann jemand darauf hinweisen, Proben zu codieren? Wie viel davon wird von Kendo direkt unterstützt?

Vielen Dank im Voraus.

Antwort

8

Diese Funktionalität wird von der Standardkonfiguration nicht unterstützt, kann jedoch durch einen benutzerdefinierten Transport erreicht werden. So erstellen Sie hybride Datenquellen, die mit dem Array localData arbeiten, wenn die Elemente verfügbar sind, und führen ansonsten Anforderungen an den Server aus.

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>

+0

Dank Alexander! Dies gibt einen guten Ausgangspunkt. – prthrokz

+0

Könnten Sie bitte Ihre Lösung posten? Ich arbeite seit Tagen an diesem jsBin-Vorschlag und kann immer noch nicht das zweite Level zur Arbeit bringen. Bitte. – Amanda

0

Nach etwas mehr Arbeit, bekam ich diese Arbeit. Ich bin mir immer noch nicht sicher, warum die localData-Variable benötigt wird, da die Kendo-Baumansicht sie anscheinend nicht verwendet, sobald ein Knoten bereits dort ist. Hier ist meine Lösung sowieso:

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

ich eine gespeicherte Prozedur unter Verwendung von Werten von 3 Tabellen in ein Baumobjekt zu lesen. Hier ist der Code für das Baumobjekt:

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

Und mein Stored Procedure:

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

AS BEGIN SET 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