Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested templates with KnockoutJS and MVC 3.0

Tags:

knockout.js

I am new to knockout JS, but am enjoying every bit that I am learning each day.

Here is my question. Based on the Loading and saving data tutorial, let's say that I have the following classes in my MVC 3.0 view model:

public class MasterModel
{
    public int Id { get; set; }
    public string Description { get; set; }
    public ICollection<ParentModel> Parents { get; set; }
}

public class ParentModel
{
    public int Id { get; set; }
    public string Description { get; set; }
    public ICollection<ChildModel> Children { get; set; }
}

public class ChildModel
{
    public int Id { get; set; }
    public string Description { get; set; }
}

And that my Index() method of the HomeController returns an instance of MasterModel with a list of ParentModel, each in turn containing a list of ChildModel. On the client side, I have the following view:

@model SomeNamespace.Models.MasterModel

(...)

<script type="text/javascript"> 
    var initialData = @Html.Raw(new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model));
    var viewModel = {
        parents: ko.observableArray(initialData.Parents),
    (...)
    };

I would like to be able to use nested templates to display the list of ParentModel bound to the MasterModel and for each ParentModel, the list of ChildrenModel. I also want both lists (ParentModel and ChildrenModel) to be observable arrays so that items of each list can be added or removed dynamically.

I have attempted to implement this following the "template" binding article on the Knockout JS site, but am not sure how to implement the observable array containing a list of... observable arrays...

Can someone point me to the right direction?

Thanks in advance!

like image 505
Talisker Avatar asked Sep 05 '11 23:09

Talisker


1 Answers

This jsFiddle example should be able to help you on the way, it works like this:

<ul data-bind="template: {name: 'TopTemplate' , foreach: masters}"></ul> 
<script type="text/html" id="TopTemplate">
    <li >    
        <p>${name}</p>
        <ul data-bind=" template: {name:  'NestedTemplate' , foreach:  parents } " style="list-style-type:circle;margin-left:15px">
        </ul>
    </li> 

</script>
<script type="text/html" id="NestedTemplate">         
    <li>
        <p>${name}</p>
        <ul data-bind=" template: {name:  'parentTemplate' , foreach:  children } " style="list-style-type:circle;margin-left:15px">
        </ul>
    </li>
</script>
 <script type="text/html" id="parentTemplate">         
    <li>
        <p>${name}</p>
    </li>
</script>

And this code:

var viewModel = {
    masters: ko.observableArray([
        {
        name: "Master1",
        parents: [{
            name: "Parent 1",
             children : [{
                name: "chlid 1"},
            {
                name: "child 2"}]},
        {
            name: "Parent 2",
             children : [{
                name: "chlid 1"},
            {
                name: "child 2"}]}]},
    {
        name: "Master2",
         parents: [{
            name: "Parent 3",
             children : [{
                name: "chlid 1"},
            {
                name: "child 2"}]},
        {
            name: "Parent 4",
             children : [{
                name: "chlid 1"},
            {
                name: "child 2"}]}]}     ])
};

// ko magic...
ko.applyBindings(viewModel);
like image 100
Major Byte Avatar answered Oct 07 '22 01:10

Major Byte