meyousikmann
meyousikmann

Reputation: 163

Using knockout binding with razor syntax

I am wondering if it is possible to use a Knockout data-bind within Razor syntax.

I have this code in my view:

<tbody data-bind="foreach: relays">
    <tr>
        <td id="body-button-column">
            <button class="btn btn-default btn-sm" title="Remove relay" data-bind="click: $parent.removeRelay">
                <i class="glyphicon glyphicon-remove-circle"></i>
            </button>
        </td>
        <td><input type="text" data-bind="value: $index"/></td>
        <td>@Html.DropDownList("RelayConfigurations[" + $index + "].Address", Model.Addresses, "Select an Item")</td>
    </tr>
</tbody>

And my viewmodel has the following property

self.relays = ko.observableArray(@Html.Raw(Json.Encode(Model.RelayConfigurations)));

where the RelayConfigurations is a collection object on the model.

In the line using the Razor syntax @Html.DropDownList.... I would like to use a knockout binding for the $index value but am not sure how to do that. Or if it is even possible.

If I replace the $index in that line with a hard-coded value of zero, the model binding in the controller action works as expected on Postback (albeit only the first relay in the collection has any data because of the hard-coded value of zero).

Upvotes: 2

Views: 7344

Answers (2)

user3189157
user3189157

Reputation:

Of course you can use knockout in razor :)

I believe what you are looking for is this anonymous object method:

@Html.DropDownList("somelist", Model.List, new { id = "listbox", data_bind = "" })

Upvotes: 6

Nathan Fisher
Nathan Fisher

Reputation: 7941

The issues as i understand it

  1. Getting the html into a format that will be easily accepted as a server-side model when the form is submitted.
  2. The ability to add items to the dropdownList from the client side.

A solution to the first issue is to look at the rendered HTML of the DropdownList and copying the resulting <select> tag then applying knockoutjs to that, that way you will keep the same format that the server is expecting to be able to turn the submitted form back into the server side model while taking advantage of knockoutjs

so you will end up with something like this

<tbody data-bind="foreach: relays">
    <tr>
        <td id="body-button-column">
            <button class="btn btn-default btn-sm" title="Remove relay" data-bind="click: $parent.removeRelay">
                <i class="glyphicon glyphicon-remove-circle"></i>
            </button>
        </td>
        <td><input type="text" data-bind="value: $index"/></td>
        <td>
           <select data-bind="attr: {id : 'RelayConfigurations[' + $index + '].Address' }, options: relays ,optionsCaption:'Select an Item'"></select>
        </td>
    </tr>
</tbody>

As for the second issue, you already have the data to data-bind to, so you can add and remove items as necessary.

From @meyousikmann comment below

Just a quick correction on the syntax for anyone else coming to this answer:

<select data-bind="attr: {name: 'RelayConfigurations[' + $index() + '].Address'}, options: $parent.addresses, optionsCaption: 'Select an Item'"></select>

Upvotes: -1

Related Questions