1
votes

Is there any way to bind a List<SelectListItem> from an MVC ViewModel to a Knockout observable array?

My Model property:

public List<SelectListItem> ListItems{ get; set; }

KO ViewModel details:

self.ListItems = ko.observableArray();

self.setModel = function (objFromServer) {
    if (!objFromServer) return;

    self.ListItems.removeAll(); // clear array first
    if (objFromServer.ListItems && objFromServer.ListItems.length > 0) {
        for (var i = 0; i < objFromServer.ListItems.length; i++) {
            var _iter_item = objFromServer.ListItems[i];
            self.ListItems.push(_iter_item);
        }
    }
}

Model binding:

    var mvcModel = ko.mapping.fromJS(@Html.Raw(Json.Encode(Model)));
    var newViewModel = new viewmodel();

    newViewModel.setModel(mvcModel);

    ko.applyBindings(newViewModel);

Razor control (currently kendo, but can be changed):

 @Html.Kendo().ComboBoxFor(x => x.Item).BindTo(Model.ListItems).SelectedIndex(0).HtmlAttributes(new { data_bind = "value: $data.Item" })

This doesn't appear to be recognising the list items at all from the knockout model end of things, all I get is an empty array (the rest of the properties are fine). Is this the best way to approach this?

2

2 Answers

1
votes

try

@(Html.Kendo().ComboBoxFor().HtmlAttributes(new { data_bind = "value: $data.Item" })
0
votes

I managed to figure this one out after a few days of pain. There was a few things that were causing issues in my case. Firstly, since it was newing up an array, and I only had one item in my test data (foolishly), I had to change check for length > 0 to >= 0. Second issue was with the way I was selecting the items. I was simply trying to push the object straight into the observable array, rather than creating an a new item.

self.ListItems = ko.observableArray();

self.setModel = function (objFromServer) {
if (!objFromServer) return;

self.ListItems.removeAll(); // clear array first
if (objFromServer.ListItems && objFromServer.ListItems.length >= 0) {
    for (var i = 0; i < objFromServer.ListItems.length; i++) {
        var _iter_item = objFromServer.ListItems()[i]; //select using ()

        //select the id and name and assign them from the select list item
        self.ListItems.push({
            id: _iter_item.Value(),
            name: _iter_item.Text()
        });
      }
   }
}