Search code examples
knockout.jspartial-views

Apply ko bindings to partial view


I have a ko viewmodel. I want to render a partial view twice on the same page. Once for physical address and once for postal address. They have the same properties, the data is just different. There is no client side knockout parent view model which contains both physical and postal addresses. I'm getting the "You cannot apply bindings multiple times to the same element." Extract below. I could create a knockout model called addresses which will contain both physical and postal and then use the with binding in a partial with 2 divs (one for postal, one for physical). I'm guessing that will work. But i don't really want to create a parent model unless necessary.Any suggestions?

Page:

@Html.Partial("_Address", Model.PhysicalAddress)
@Html.Partial("_Address", Model.PostalAddress)

Partial:

@model Models.AddressDetailsViewModel
<div id="myDiv">
        <table class="my-table">
                <tr>
                    <td id="postalCode">
                        <span data-bind="text: props.postalCode">
                        </span>
                    </td>
                </tr>               
        </table>
    </div>

<script type="text/javascript">
    var data = @(Html.Raw(Json.Encode(Model)));
    var viewModel = mapAddress(data);
    ko.applyBindings(viewModel, $("#myDiv")[0]);
</script>

Solution

  • You can use the with binding in Knockout to bind parts of a ViewModel to a reusable partial view. I wrote a blog article about this a while back:

    https://conficient.wordpress.com/2013/03/07/knockout-multiple-viewmodels-and-reusable-partial-views/

    I actually used addresses as the example in my sample code so you should find this helps a lot. In your sample you would do it this way:

    <div data-bind="with: physicalAddress">
        @Html.Partial("_Address")
    </div>
    
    <div data-bind="with: postalAddress">
        @Html.Partial("_Address")
    </div>
    

    This assumes that the two DIVs are within the main ViewModel binding context. Note that if either address is undefined or null, the address HTML won't be visible.

    Knockout version 3.2 introduced the concept of components as @shailendra-kumar has also pointed out. In the longer term, this is a better approach, but partial views should also work.