Lazy-Loading and OData

This example shows how you can use the TreeView control to display hierarchical data from OData sources.

The sample starts by loading the Northwind employees table. When the data is loaded, the code adds an "Orders" empty array to each employee. The lazyLoadFunction is used to load the orders when an employee node is expanded.

The orders table also adds an "Order_Details" empty array to each order. The lazyLoadFunction is used to load the order details when an order node is expanded.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// This file locates: "Scripts/Lesson/C1Nav/LazyOdata.js".
c1.documentReady(function () {
    var theTree = wijmo.Control.getControl('#theTree');
    theTree.displayMemberPath = ['FullName', 'ShipName', 'Summary'];
    theTree.childItemsPath = ['Orders', 'Order_Details'];
    theTree.lazyLoadFunction = lazyLoadODataFunction;
 
    // lazy-load orders and details
    function lazyLoadODataFunction(node, callback) {
        switch (node.level) {
 
            // load orders for an employee
            case 0:
                var url = 'Employees(' + node.dataItem.EmployeeID + ')/Orders?$format=json&$inlinecount=allpages&$select=OrderID,ShipName,ShipCountry';
                var orders = [];
                getOdata(url,
                    function (value) {
                        orders = orders.concat(value);
                    },
                    function () {
                        orders.forEach(function (item) {
                            item.Order_Details = [];
                        });
                        callback(orders);
                    });
                break;
 
                // load extended details for an order
            case 1:
                var url = "Order_Details_Extendeds/?$format=json&$inlinecount=allpages&select=ProductName,ExtendedPrice&$filter=OrderID eq " + node.dataItem.OrderID;
                var orderDetails = [];
                getOdata(url,
                    function (value) {
                        orderDetails = orderDetails.concat(value);
                    },
                    function () {
                        orderDetails.forEach(function (item) {
                            item.Summary = wijmo.format('{ProductName}: {ExtendedPrice:c}', item);
                        });
                        callback(orderDetails);
                    });
                break;
 
                // default
            default:
                callback(null);
        }
    }
 
    // get data from OData service   
    function getOdata(url, fill, finish) {
        wijmo.httpRequest(nwindService + url, {
            success: function (xhr) {
                var data = JSON.parse(xhr.responseText);
                fill(data.value);
 
                var nextLink = data['odata.nextLink'];
                if (nextLink == null) {
                    finish();
                } else {
                    getOdata(nextLink + '&$format=json', fill, finish);
                }
            }
        });
    }
 
    var employees = [];
    getOdata('Employees?$format=json&$inlinecount=allpages&$select=EmployeeID,FirstName,LastName',
        function (value) {
            employees = employees.concat(value);
        },
        function () {
            employees.forEach(function (item) {
                item.FullName = item.FirstName + ' ' + item.LastName;
                item.Orders = [];
            });
            theTree.itemsSource = employees;
        });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// This file locates: "Content/css/Lesson/C1Nav/LazyOdata.css".
/* level 0 nodes and deeper (employees...) */
.demo-control .wj-treeview .wj-nodelist > .wj-node {
    font-weight: bold;
}
 
/* level 1 nodes and deeper (orders...) */
.demo-control .wj-treeview .wj-nodelist > .wj-nodelist > .wj-node {
    font-weight: normal;
    font-size: 95%;
    color: darkblue;
}
 
/* level 2 nodes and deeper (order details...) */
.demo-control .wj-treeview .wj-nodelist > .wj-nodelist > .wj-nodelist > .wj-node {
    font-size: 90%;
    color: darkslategrey;
}
 
/* default trees on this sample */
.demo-control .wj-treeview {
    display:block;
    height: 350px;
    margin-top: 8px;
    margin-bottom: 8px;
    padding: 6px;
    background: #f0f0f0;
    box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
using System.Web.Mvc;
 
namespace LearnMvcClient.Controllers
{
    public partial class C1NavController : Controller
    {
        // GET: LazyOdata
        public ActionResult LazyOdata()
        {
            return View();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h1>
    @Html.Raw(Resources.C1Nav.LazyOdata_Title)
</h1>
 
<p>
    @Html.Raw(Resources.C1Nav.LazyOdata_Text1)
</p>
<p>
    @Html.Raw(Resources.C1Nav.LazyOdata_Text2)
</p>
<p>
    @Html.Raw(Resources.C1Nav.LazyOdata_Text3)
</p>
 
@Html.C1().TreeView().Id("theTree")