MVC Parent Child ForEach Loop

Collections

// //

Collections

Live example

  • Annabelle has 4 children: Add child

    • Arnie (child rendered at 58)
    • Anders (child rendered at 58)
    • Apple (child rendered at 58)
    • New child (child rendered at 58)
  • Bertie has 4 children: Add child

    • Boutros-Boutros (child rendered at 58)
    • Brianna (child rendered at 58)
    • Barbie (child rendered at 58)
    • Bee-bop (child rendered at 58)
  • Charles has 2 children: Add child

    • Cayenne (child rendered at 58)
    • Cleopatra (child rendered at 58)

Show render times//

Model

public class CollectionsPersonModel
{
    public string Name { get; set; }
    public List<string> Children { get; set; }
}

public class CollectionsModel
{
    public bool ShowRenderTime { get; set; }
    public List<CollectionsPersonModel> People { get; set; }

    public void AddChild(int index)
    {
        if (index >= 0 && index < People.Count)
            People[index].Children.Add("New child");
    }
}

Razor

@using PerpetuumSoft.Knockout
@model KnockoutMvcDemo.Models.CollectionsModel
@{
  var ko = Html.CreateKnockoutContext();
}
<ul>
  @using (var people = ko.Foreach(m => m.People))
  {    
    <li>
      <div>
        @people.Html.Span(m => m.Name) has @people.Html.Span(m => m.Children.Count) children:
        @ko.Html.Button("Add child", "AddChild", "Collections", new { index = people.GetIndex() })
      </div>
      <ul>
        @using (var children = people.Foreach(m => m.Children))
        {
          <li>
            @children.Html.Span(m => m)
            <span @ko.Bind.Visible(m => m.ShowRenderTime)>(child rendered at @ko.Html.SpanInline("new Date().getSeconds()"))
            </span></li>
        }
      </ul>
    </li>
  }
</ul>
@ko.Html.CheckBox(m => m.ShowRenderTime) Show render times

@ko.Apply(Model)

Controller

public class CollectionsController : BaseController
{
    public ActionResult Index()
    {
        InitializeViewBag("Collections");
        var model = new CollectionsModel();
        model.People = new List<CollectionsPersonModel>();
        model.People.Add(new CollectionsPersonModel
        {
            Name = "Annabelle",
            Children = new List<string> { "Arnie", "Anders", "Apple" }
        });
        model.People.Add(new CollectionsPersonModel
        {
            Name = "Bertie",
            Children = new List<string> { "Boutros-Boutros", "Brianna", "Barbie", "Bee-bop" }
        });
        model.People.Add(new CollectionsPersonModel
        {
            Name = "Charles",
            Children = new List<string> { "Cayenne", "Cleopatra" }
        });
        return View(model);
    }

    public ActionResult AddChild(CollectionsModel model, int index)
    {
        model.AddChild(index);
        return Json(model);
    }
}

Html (autogenerated)

<ul>
<!-- ko foreach: People -->
    <li>
      <div>
        <span data-bind="text : $data.Name"></span> has <span data-bind="text : $data.Children().length"></span> children:
        <button data-bind="click : function() {executeOnServer(viewModel, '/Collections/AddChild?index='+$index()+'');}">Add child</button>
      </div>
      <ul>
<!-- ko foreach: $data.Children -->
          <li>
            <span data-bind="text : $data"></span>
            <span data-bind="visible : $parents[1].ShowRenderTime()">(child rendered at <span data-bind="text : new Date().getSeconds()"></span>)
            </span></li>
<!-- /ko -->
      </ul>
    </li>
<!-- /ko -->
</ul>
<input data-bind="checked : ShowRenderTime" type="checkbox" /> Show render times

<script type="text/javascript"> 
var viewModelJs = {"ShowRenderTime":false,"People":[{"Name":"Annabelle","Children":["Arnie","Anders","Apple"]},{"Name":"Bertie","Children":["Boutros-Boutros","Brianna","Barbie","Bee-bop"]},{"Name":"Charles","Children":["Cayenne","Cleopatra"]}]};
var viewModel = ko.mapping.fromJS(viewModelJs); 
ko.applyBindings(viewModel);
</script>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s