Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 489
newbie_86 Avatar asked Sep 28 '22 19:09

newbie_86


2 Answers

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.

like image 183
Quango Avatar answered Oct 05 '22 08:10

Quango


My suggestion is to use Knockout Components which was introduced in 3.2.0 version. http://knockoutjs.com/documentation/component-registration.html

Create the Knockout component and send the data in parameters once for physical address and once for postal address.

like image 33
shailendra kumar Avatar answered Oct 05 '22 06:10

shailendra kumar