This is a migrated thread and some comments may be shown as answers.

Using Complex Objects, Data Source & MVVM Nested Templates

1 Answer 925 Views
Data Source
This is a migrated thread and some comments may be shown as answers.
Code.Combustion
Top achievements
Rank 1
Code.Combustion asked on 21 Jul 2013, 01:31 AM
Hi Everyone,

I'm the lead developer on an ASP.NET WebForms project (Sadly, this choice was mine just prior to my arrival and the lead at the time left shortly thereafter leaving me stuck with a less than preferred ASP.NET option).
Anyways, I recently recommended purchase of 2 licenses for the DevCraft Complete package to my employeer. One license is mine while the other goes to another developer who strongly prefers the ASP.NET AJAX controls for WebForms. We're both preparing some proof of concepts to present to the project manager. I need to show that using Kendo UI with MVVM  will offer better performance both client and server side, less latency, less bandwidth and the easiest to learn for our other developers.

I need to create a simple read-only page which uses two models . For each Category I need to display the Name. Just under this header, For each Ticket associated with this category, I need to display the Name and Date of submission for the 20 most recent tickets (I intend to use serverPaging on the DataSource). I then want to attach a click handler to each Ticket Name which will make a call and pass the ID of this Ticket causing the system to return the content for this ticket which will be displayed in a pop-up window.

As my business objects typically contain more properties than I need for a given page - we're creating the JSON models separately. (Fig 1a & 1b respectively)

What I first tried was creating a web service call which returns  an array of Category objects which each contain the Tickets associated with that Category. The JSON for this can be seen in Fig 2.

I've found mixed examples switching between a standard DataSource and a HierarchicalDataSource for this scenario. My current javascript can be seen in Fig 3.

Finally the MVVM portion -- the HTML can be seen in Fig 4. I don't feel this is too complex but it seems some I'm missing a few things. When I run this, only the Categories JSON is returned and no binding occurs. No errors are thrown either.

These are the entity models server side:
Fig. 1a
01.namespace ProofOfConcept.BO
02.{
03.    public class Ticket
04.    {
05.        public int ID { get;set; }
06.        public int CategoryID { get;set; }
07.        public string Name { get;set; }
08.        public string Content { get;set; }
09.        public DateTime DateSubmitted { get;set; }
10.    }
11. 
12.    public class Category
13.    {
14.        public int ID { get;set; }
15.        public string Name { get;set; }
16.        public List<Ticket> Tickets { get;set; }
17.    }
18.}



These are the models which I serialize into JSON. I read that I should modify them as shown below -- see comments.

Fig 1b
01.namespace ProofOfConcept.JSONModels
02.{
03. 
04.    public class Ticket
05.    {
06.        // Key values are encrypted into a string before being sent to the client
07.        public string ID { get;set; }
08.        public string CategoryID { get;set; }
09.        public string Name { get;set; }
10.        public string Content { get;set; }
11. 
12.        // I would prefer a DateTime value but I don't know if
13.        // converting the value and displaying it properly is supported
14.        public string DateSubmitted { get; set; }
15.    }
16. 
17.    public class Category
18.    {
19.        // Key values are encrypted into a string before being sent to the client
20.        public string ID { get;set; }
21.        public string Name { get;set; }
22.     
23.        // I read that the property for the nested object(s) should
24.        // be removed from the JSON model -- is this correct? 
25.        // public List<Ticket> Tickets { get;set; }
26.    }
27. 
28.}

Is it possible that I can just send all the data across in this format from just one handler and have the MVVM function with the nested templates? or am I correct that I must use a HierarchicalDataSource? If so, do I have it correctly implemented as shown below?

Fig 2
01.[
02.    {
03.        "ID": "1",
04.        "Name": "CategoryName1",
05.        "Tickets": [
06.            {
07.                "ID": "10",
08.                "Name": "name value",
09.                "CategoryID": "1",
10.                "Content": "content here",
11.                "DateSubmitted": "serialized DateTime here"
12.            },
13.            {
14.                "ID": "11",
15.                "Name": "name value",
16.                "CategoryID": "1",
17.                "Content": "content here",
18.                "DateSubmitted": "serialized DateTime here"
19.            },
20.            {
21.                "ID": "12",
22.                "Name": "name value",
23.                "CategoryID": "1",
24.                "Content": "content here",
25.                "DateSubmitted": "serialized DateTime here"
26.            }
27.        ]
28.    }, // ... Removed for readability
29.]

This is the javascript I've got so far -- I've bounced between a simple DataSource and a HierarchicalDataSource but I've been unable to find enough examples on this site (with the documentation and forums) that nail down a concrete implementation.

Fig 3
01.$(document).ready(function ()
02.{
03.    // Objects are defined individually as I want to create
04.    // a single file with all object definitions so that other
05.    // developers can recycle them.
06.    var Ticket = kendo.data.Model.define(
07.    {
08.        id: "ID",
09.        fields:
10.        {
11.            ID: { type: "string" },
12.            CategoryID: { type: "string" },
13.            Name: { type: "string" },
14.            Content: { type: "string" },
15. 
16.            // Is there a Date (or DateTime) type?
17.            DateSubmitted: { type: "string" },
18.            hasChildren: false
19.        }
20.    });
21. 
22.    var Category = kendo.data.Model.define(
23.    {
24.        id: "ID",
25.        fields:
26.        {
27.            ID: { type: "string" },
28.            Name: { type: "string" },
29.            hasChildren: true,
30.            children: Tickets
31.        }
32.    });
33. 
34.    // The ID of the Category is passed to the handler 
35.    // in this format: Tickets.ashx?CID=2
36.    // If possible, I'd also like to pass the ID of the ticket,
37.    // Tickets.ashx?ID=44 which would return the full Ticket (ie: with Content)
38.    var Tickets =
39.    {
40.        transport:
41.        {
42.            read:
43.            {
44.                 url: "Tickets.ashx",
45.                 type: "GET",
46.                 dataType: "json",
47.                 contentType: "application/json; charset=utf-8"
48.            }
49.         },
50.         schema:
51.         {
52.            data: "d",
53.            model: Ticket
54.         }
55.    };
56. 
57. 
58.    var Categories = new kendo.data.HierarchicalDataSource(
59.    {
60.        transport:
61.        {
62.            read:
63.            {
64.                url: "Categories.ashx",
65.                type: "GET",
66.                dataType: "json",
67.                contentType: "application/json; charset=utf-8"
68.            }
69.        },
70.        schema:
71.        {
72.            data: "d",
73.            model: Category
74.        }
75.    });
76. 
77. 
78.    var viewModel = kendo.observableHierarchy(
79.    {
80.            Categories: Categories
81.    });
82. 
83.    kendo.bind($("#divCategory"), viewModel);
84. 
85.});
Fig 4
01.<section>
02. 
03.   <div id="divCategory" data-template="category-template" data-bind="source: Categories" >
04.       <ul data-template="ticket-template" data-bind="source: Tickets" id="divTicket">
05.       </ul>
06.   </div>
07. 
08.   <script id="category-template" type="text/x-kendo-template">
09.       <h2 data-bind="text: Name"></h2>
10.   </script>
11. 
12. <script id="ticket-template" type="text/x-kendo-template">
13.       <li>
14.           <a data-bind="attr: { href: ID }">
15.               <span data-bind="text: Name" ></span>
16.           </a>
17.           <span data-bind="text: DateSubmitted" ></span>
18.       </li>
19. </script>
20. 
21.</section>

I look forward to your reply.

Thank you,

1 Answer, 1 is accepted

Sort by
0
Daniel
Telerik team
answered on 24 Jul 2013, 12:39 PM
Hello,

For the provided data I would suggest to use a treeview as the binding will work out of the box and you can customize the appearance with a template. It is also possible to bind the data directly but please note the following:

  • Only the widgets support binding directly to a dataSource. The source binding accepts an array or an object.
  • The observableHierarchy is used to bind hierarchical inline data to the TreeView and it expects an array as parameter to the constructor.
  • The HierarchicalDataSource uses Node instead of Model and also the children and hasChildren fields should be set to the Node instead to the fields.
  • The template used for the source binding should have a single root element in order for the model to be bound correctly.

I created two jsBin examples showing how the binding can be implemented with both a DataSource and a HierarchicalDataSource.

Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
Data Source
Asked by
Code.Combustion
Top achievements
Rank 1
Answers by
Daniel
Telerik team
Share this question
or