2013-12-09 14 views
6

Sto usando Kendo UI TreeView per caricare i dati gerarchici nella mia pagina web. Per impostazione predefinita, sto caricando i dati fino a 3 livelli (per esempio Root -> Root directs -> Root directs 'directs). Ho bisogno di un modo per caricare pigramente i nodi rimanenti mentre l'utente si espande ulteriormente lungo la struttura. Inoltre, i dati già recuperati devono essere memorizzati nella cache locale per evitare chiamate non necessarie per nodi già espansi. Sono nuovo di Kendo UI e non ho abbastanza tempo per passare attraverso la documentazione. JSON sembraCaricamento lento nella vista ad albero dell'interfaccia utente Kendo con memorizzazione nella cache

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

Qualcuno può notare a esempi di codice? Quanto di quanto sopra è supportato da Kendo?

Grazie in anticipo.

risposta

8

Questa funzionalità non è supportata dalla configurazione predefinita, ma può essere ottenuta tramite un trasporto personalizzato. Ecco come creare origini dati ibride che funzionano con l'array localData se gli articoli sono disponibili e, in caso contrario, eseguono richieste al server.

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

Grazie Alexander! Questo dà un buon punto di partenza. – prthrokz

+0

Potresti per favore pubblicare la tua soluzione? Ho lavorato da quel suggerimento di jsBin per giorni e ancora non riesco a far funzionare il secondo livello. Per favore. – Amanda

0

Dopo un po 'più di lavoro, ho avuto questo lavoro. Non sono ancora sicuro del motivo per cui è necessaria la variabile localData, dal momento che la vista ad albero del Kendo non sembra usarla quando un nodo è già lì. Ecco la mia soluzione in ogni caso:

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

che sto utilizzando una stored procedure per leggere i valori da 3 tavoli in un oggetto Tree. Ecco il codice per l'oggetto Albero:

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

E la mia 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 

FINE