Skip to content

Commit 39b4b24

Browse files
docs(treeview): load on demand example
1 parent 7b72922 commit 39b4b24

File tree

1 file changed

+109
-3
lines changed

1 file changed

+109
-3
lines changed

components/treeview/data-bind.md

Lines changed: 109 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ The following **Example** shows how to define simple binding to match item field
7676

7777
### Multiple Level Bindings
7878

79-
You can define different binding settings for the different levels of nodes in a treeview. With this, the children of a node can consume a different field than their parent, and this may make your application more flexible. If you use hierarchical data binding, the children can even use a different model from their parent.
79+
You can define different binding settings for the different levels of nodes in a treeview. With this, the children of a node can consume a different field than their parent, and this may make your application more flexible. If you use [hierarchical data binding](#hierarchical-data), the children can even use a different model from their parent.
8080

8181
This also allows you to define a different `ItemTemplate` for different levels.
8282

@@ -275,7 +275,7 @@ Hierarchical data means that the collection child items is provided in a field o
275275

276276
This lets you gather separate collections of data and/or use different models at each different level. Note that the data binding settings are per level, so a certain level will always use the same bindings, regardless of the model they represent and their parent.
277277

278-
>caption Example of hierarchical data that uses different models for the parent and the child
278+
>caption Example of hierarchical data that uses different models for the parent and the child. Using different models is not required.
279279
280280
````CSHTML
281281
@using Telerik.Blazor.Components.TreeView
@@ -345,7 +345,113 @@ This lets you gather separate collections of data and/or use different models at
345345

346346
## Load On Demand
347347

348+
You don't have to provide all the data the treeview will render at once - the root nodes are sufficient for an initial display. You can then use the `OnExpand` event of the treeview to provide [hierarchical data](#hierarchical-data) to the node that was just expanded. Loading nodes on demand can improve the performance of your application by requesting less data at any given time.
349+
350+
>caption Load on Demand in a TreeView with sample handling of the various cases. Review the code comments for details.
351+
352+
````CSHTML
353+
@using Telerik.Blazor.Components.TreeView
354+
355+
<TelerikTreeView Data="@HierarchicalData" OnExpand="@LoadChildren">
356+
<TelerikTreeViewBindings>
357+
<TelerikTreeViewBinding TextField="Category" ItemsField="Products"></TelerikTreeViewBinding>
358+
<TelerikTreeViewBinding Level="1" TextField="ProductName"></TelerikTreeViewBinding>
359+
</TelerikTreeViewBindings>
360+
</TelerikTreeView>
361+
362+
@code {
363+
public List<ProductCategoryItem> HierarchicalData { get; set; }
364+
365+
public class ProductCategoryItem
366+
{
367+
public string Category { get; set; }
368+
public int CategoryId { get; set; } //will be used to identify the node, not for rendering in this example
369+
public List<ProductItem> Products { get; set; }
370+
public bool Expanded { get; set; }
371+
public bool HasChildren { get; set; }
372+
}
373+
374+
public class ProductItem
375+
{
376+
public string ProductName { get; set; }
377+
// the following fields are to denote you can keep having hierarchy further down. They are not required
378+
// they are not really used in this example and you would have a collection of child items too
379+
// see the information about multiple data bindings earlier in this article on using them
380+
public bool Expanded { get; set; }
381+
public bool HasChildren { get; set; }
382+
}
383+
384+
protected override void OnInit()
385+
{
386+
LoadRootHierarchical();
387+
}
388+
389+
private void LoadRootHierarchical()
390+
{
391+
HierarchicalData = new List<ProductCategoryItem>();
392+
393+
HierarchicalData.Add(new ProductCategoryItem
394+
{
395+
Category = "Category 1",
396+
HasChildren = true, // allow the user to expand the item and load children on demand
397+
CategoryId = 1 // an identifier for use in the service call for child items
398+
});
399+
400+
HierarchicalData.Add(new ProductCategoryItem
401+
{
402+
Category = "Category 2",
403+
HasChildren = true,
404+
CategoryId = 2
405+
});
406+
}
407+
408+
private async void LoadChildren(TreeViewExpandEventArgs args)
409+
{
410+
// check if the item is expanding, we don't need to do anything if it is collapsing
411+
// in this example we will also check the type of the model to know how to identify the node and what data to load. If you use only one model for all levels, you don't have to do this
412+
if (args.Expanded && args.Item is ProductCategoryItem)
413+
{
414+
ProductCategoryItem currCategory = args.Item as ProductCategoryItem;
415+
if (currCategory.Products?.Count > 0)
416+
{
417+
return; // item has been expanded before so it has data, don't load data again
418+
// alternatively, load it again but make sure to handle the child items correctly
419+
// either overwrite the entire collection, or use some other logic to append/merge
420+
}
421+
int itemIdentifier = currCategory.CategoryId;
422+
// in a similar fashion, you can identify the item that was just expanded through its properties
423+
// in this example, we will hardcode some data and logic for brevity
424+
// in a real case, you would probably await a remote endpoint/service
425+
426+
if (itemIdentifier == 2) // simulate no data for a certain node - the second in our example
427+
{
428+
currCategory.HasChildren = false; // remove the expand icon from the node
429+
430+
StateHasChanged(); // inform the UI that the data is changed
431+
432+
return;
433+
}
434+
435+
// data requested and received for a certain node
436+
List<ProductItem> theProducts = new List<ProductItem>() {
437+
new ProductItem { ProductName= $"Category {itemIdentifier} - Product 1" },
438+
new ProductItem { ProductName= $"Category {itemIdentifier} - Product 2" }
439+
};
440+
441+
// one way to add child elements to a collection
442+
currCategory.Products = new List<ProductItem>();
443+
currCategory.Products.AddRange<ProductItem>(theProducts);
444+
445+
StateHasChanged(); // inform the UI that the data is changed
446+
}
447+
}
448+
}
449+
````
450+
348451
## See Also
349452

350-
* [Live Demo: TreeView Data Bindings](https://demos.telerik.com/blazor-ui/treeview/bindings)
453+
* [Live Demo: TreeView Flat Data](https://demos.telerik.com/blazor-ui/treeview/flat-data)
454+
* [Live Demo: TreeView Hierarchical Data](https://demos.telerik.com/blazor-ui/treeview/hierarchical-data)
455+
* [Live Demo: TreeView Per-Level Data Bindings](https://demos.telerik.com/blazor-ui/treeview/bindings)
456+
* [Live Demo: TreeView Load on Demand](https://demos.telerik.com/blazor-ui/treeview/lazy-loading)
351457

0 commit comments

Comments
 (0)