Reputation: 1053
Ok so i have a view with this so far
function AppViewModel() {
this.title = ko.observable("@Model.Title");
this.firstName = ko.observable("@Model.FirstName");
this.lastName = ko.observable("@Model.LastName");
this.fullName = ko.computed(function () {
return this.title() + " " + this.firstName() + " " + this.lastName();
}, this);
}
@{
var jsList = Html.Raw(JsonConvert.SerializeObject(ViewBag.Countries));
}
function newViewModel() {
var theAppViewModel = new AppViewModel()
var g = ko.mapping.fromJS(theAppViewModel);
var viewModel = { vm: ko.observable([]) }
viewModel.vm = ko.mapping.fromJS(@jsList);
ko.applyBindings(g);
}
// Activates knockout.js
$(document).ready(function () {
ko.applyBindings(new newViewModel());
});
<ul style="list-style-type: none; float: left; margin-top: 20px; ">
<li>
@Html.LabelFor(model => model.Title)
<input data-bind="value: title"/>
</li>
<li>
@Html.LabelFor(model => model.FirstName)
<input data-bind="value: firstName" />
</li>
<li>
@Html.LabelFor(model => model.LastName)
<input data-bind="value: lastName" />
</li>
<li>
Full Name
<Span data-bind="text: fullName"></Span>
</li>
<li>
Coutries:
<select data-bind="foreach: vm">
<option data-bind="text: CountryName"></option>
</select>
</li>
</ul>
My Controller has this on it,
public ActionResult Index()
{
//ViewBag.Message = "KO js in mvc 4";
ViewBag.Countries = new List<Country>(){
new Country()
{
Id = 1,
CountryName = "America",
Abbreviation = "USA"
},
new Country()
{
Id = 2,
CountryName = "United Kingdon",
Abbreviation = "UK"
},
new Country()
{
Id = 3,
CountryName = "Irland",
Abbreviation = "IRL",
}
};
var vm = new PersonViewModel()
{
Id = 1,
DateOfBirth = new DateTime(1993, 01, 22),
Title = "Miss",
FirstName = "Jamie",
LastName = "Oscar",
};
return View(vm);
}
I can return the List from the controller in a standard loop like this:
<select>
@foreach(var c in ViewBag.Countries)
{
<option>@c.CountryName</option>
}
</select>
But I would like to bind the results to the list Via Knockout.js.
Upvotes: 2
Views: 2628
Reputation: 1053
it has now come to my attention that I can now bind knockout Json result to a @html.DropDownListFor
attribute helper and still bind my data from knockout I have a DropDown list that is populated by knockout json array object, but then also bind this to the MVC 4 model this can be then used in the controller and the passed back to WCF or Linq to SQL for database
@Html.DropDownListFor(m => m.SelectedAuthType,
(SelectList)Model.authlevellistItems,
new { id = "alddl", data_bind = " options: Countries, optionsText: 'CountryName', optionsValue: 'Id'" })
works perfectly with models now as well as JSON knockout results.
Upvotes: 0
Reputation: 49123
Your current viewModel
that is containing the countries list is not bound, the only bound View-Model is the g
you're calling applyBinding()
with. Also, there's no point calling applyBinding()
twice (on the same element).
Try this instead:
$(document).ready(function() {
var vm = new AppViewModel();
vm.Countries = ko.mapping.fromJS(@jsList);
ko.applyBindings(vm);
});
<select data-bind="value: countryId,
options: Countries,
optionsText: 'CountryName',
optionsValue: 'Id'"></select>
Please keep in mind that the value
directive is referring to the chosen CountryId of the person
but you currently don't have such a field in your View-Model.
Consider adding it as well:
var vm = new PersonViewModel()
{
Id = 1,
DateOfBirth = new DateTime(1993, 01, 22),
Title = "Miss",
FirstName = "Jamie",
LastName = "Oscar",
CountryId = 1
};
function AppViewModel() {
this.title = ko.observable("@Model.Title");
this.firstName = ko.observable("@Model.FirstName");
this.lastName = ko.observable("@Model.LastName");
this.countryId = ko.observable(@Model.CountryId);
}
Upvotes: 1