sergej.art
sergej.art

Reputation: 149

ASP.NET MVC 4 & KNOCKOUT.JS

I have 2 Dropdown lists populated with knockout.js and I have 2 questions:

1)Why this one is populated from the Model.StreetList

@Html.DropDownListFor(m => m.SelectedStreet, Model.StreetList, new {onchange = "FetchHouses();"})

But this doesn't

    @Html.DropDownListFor(m => m.SelectedStreet, Model.StreetList, new {onchange = "FetchHouses();", @data_bind = "options: StreetList, optionsText: 'Name', optionsValue: 'Id', optionsCaption: 'Select...'"})

So is it possible to populate it by default from Model, but if some event happens populate it with knockout binding?

2)After form submission if ModelState is invalid selected values for those 2 droplists are lost. How do I solve this?

<p>
    @Html.LabelFor(m => m.SelectedStreet, @Resources.RegistrationStreet)
    @Html.DropDownListFor(m => m.SelectedStreet, Model.StreetList, new {onchange = "FetchHouses();", @data_bind = "options: StreetList, optionsText: 'Name', optionsValue: 'Id', optionsCaption: 'Select...'"})
</p>
<p>
    @Html.LabelFor(m => m.SelectedHouse, @Resources.RegistrationHouse)
    @Html.DropDownListFor(m => m.SelectedHouse, Model.HouseList, new { @data_bind="options: HouseList, optionsText: 'Number', optionsValue: 'Id'"})
</p>

Any help appreciated!

Edit:

knockout.js binding happens on change events and it works fine, problem is that while change event is not fired I would like to populate drop downs from the MVC Model Here is js code which does binding:

function CascadingDdLViewModelStreet() {
    this.StreetList = ko.observableArray([]);
    this.HouseList = ko.observableArray([]);
}

var objVMStreet = new CascadingDdLViewModelStreet();
ko.applyBindings(objVMStreet);

function FetchStreets() {
    objVMStreet.HouseList([]);
    objVMStreet.StreetList([]);
    var cityCode = $("#SelectedCity").val();
    $.getJSON("/Account/GetStreets/" + cityCode, null, function(data) {
        objVMStreet.StreetList(data);
    });

}

function FetchHouses() {
    var streetCode = $("#SelectedStreet").val();
    $.getJSON("/Account/GetHouses/" + streetCode, null, function(data) {
        objVMStreet.HouseList(data);
    });
}

Here is a full code:

View: http://pastebin.com/jva9ff8A

Model: http://pastebin.com/vDQkg0d5

Controller: http://pastebin.com/avBuRy9D

Upvotes: 0

Views: 2425

Answers (1)

Ruslan
Ruslan

Reputation: 10147

1.try populating ko model with data from MVC model like so:

function CascadingDdLViewModelStreet() {
  this.StreetList = ko.observableArray(@Html.Raw(Json.Encode(Model.StreetList)));
  this.HouseList = ko.observableArray([]);
}

2.You need to pass the model (even though invalid) with SelectedStreet & SelectedHouse populated back to the View.

Upvotes: 1

Related Questions