Search code examples
asp.net-mvcknockout.jsknockout-mapping-plugin

Knockout mapping plugin trouble getting binding properties


I'm trying to understand knockout in combination with the knockout mapping plugin.

I've an asp.net MVC application returning a model (an array of customers).

My controller:

Public ActionResult Index()
{
    List<Customer> customers = new List<Customer>{
         .....initializing-code for the customerlist

         };
    return View(customers);
}

in my View i have a script as follows:

<script type="text/javascript">
    function ViewModel() {
        var self = this;
    };

    var myViewModel;

    $(function() {
        var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
        myViewModel = ko.mapping.fromJSON(jsonModel, {}, new ViewModel());
        ko.applyBindings(myViewModel);
    });

</script>

I wanna make a controlflow binding using a foreach......whats the variable name for this foreach binding. I tried '$data' but that doesn't seem to work.

kind regards

Relevant view Code:

<div class="row" data-bind="foreach: customers">
    <div class="col-md-2">
    <span data-bind="text: Name"></span>
</div>
<div class="col-md-2">
    <span data-bind="text: FirstName"></span>&nbsp;<span data-bind="text: LastName"></span>
</div>
<div class="col-md-2">
    <span data-bind="text: ContactStreet"></span>&nbsp;<span data-bind="text: ContactBuildingNumber"></span>
</div>
<div class="col-md-2">
    <span data-bind="text: ContactPostalCode"></span>
</div>
<div class="col-md-2">
    <span data-bind="text: ContactCity"></span>
</div>
<div class="col-md-2">
    <button class="btn btn-success">Edit</button>
    <button class="btn btn-danger">Delete</button>
</div>

@section scripts{
@Scripts.Render("~/bundles/knockout")
<script type="text/javascript">
    function ViewModel() {
        var self = this;


    };

    var myViewModel = {};

    $(function() {
        var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
        myViewModel.customers = ko.mapping.fromJSON(jsonModel, {}, new ViewModel());
        ko.applyBindings(myViewModel);
    });

</script>

Solution

  • As you have it, you can bind to it like this

    <div data-bind="foreach: $root">
        <span data-bind="text: Name"></span> 
        ... etc ...
    </div>
    

    BUT, I would do it like this

    var myViewModel = {};
    
    $(function() {
        var jsonModel = '@Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(this.Model, new Newtonsoft.Json.Converters.IsoDateTimeConverter()))';
        myViewModel.customers = ko.mapping.fromJS(jsonModel);
        ko.applyBindings(myViewModel);
    });
    

    Then you can put in your markup

    <div data-bind="foreach: customers">
        <span data-bind="text: Name"></span> 
        ... etc ...
    </div>
    

    Because now you can add more properties to your viewmodel, which you surely will need.

    UPDATE: Here's a working jsfiddle. Remember the call is fromJS, not fromJSON.