Reputation: 22424
I am trying to work out how I bind multiple models from a master model to different parts of my HTML mark up. The HTML part is:-
<ul data-bind="foreach: { data: members}">
<li>
<span data-bind="text: MemberId"></span>
<span data-bind="text: Name"></span>
<span data-bind="text: SwagCompany"></span>
<span data-bind="text: SwagThing"></span>
</li>
</ul>
<span data-bind="text: winner.Name"></span>
But can't work out how to bind the winner.Name
, my model looks like this:-
var masterViewModel = {
vmA : { ...},
vmB : { ... }
}
ko.applyBindings({
winner: ko.observable(masterViewModel.vmB),
members: ko.observableArray(mappedData),
...
}
Obviously I am misunderstanding how to applyBindings correctly. I have the following code as a plunker showing an example of what I am trying to do:-
<script>
$(function () {
var masterViewModel = {
vmA: function memberViewModel(data) {
this.Id = data.MemberId;
this.MemberId = ko.observable(data.MemberId);
this.Name = ko.observable(data.Name);
this.SwagCompany = ko.observable("");
this.SwagThing = ko.observable("");
this.Photo = ko.observable(data.Photo);
},
vmB: {
Name: "Initial winner..."
}
};
$.getJSON("/home/memberlist")
.then(function (rawData) {
return ko.utils.arrayMap(rawData, function (instanceData) {
return new masterViewModel.vmA(instanceData);
});
})
.done(function (mappedData) {
doit(mappedData);
});
function doit(mappedData) {
ko.applyBindings({
winner: ko.observable(masterViewModel.vmB),
members: ko.observableArray(mappedData),
getNextWinner: function () {
var members = this.members();
var winner = this.winner();
//console.log(ddd.Name());
$.getJSON("/home/nextwinner")
.then(function (rawData) {
var nextWinner = ko.utils.arrayFirst(members, function (member) {
return member.Id === rawData.Winner.MemberId;
});
nextWinner.SwagThing(rawData.WonSwag.Thing);
nextWinner.SwagCompany(rawData.WonSwag.Company);
winner.Name(rawData.Winner.Name);
});
}
});
}
});
</script>
Upvotes: 0
Views: 177
Reputation: 10349
Your code is very messy, as you're creating a viewModel object within your applybindings call, and creating viewModel objects directly. Use the constructor syntax, and create new instances of your viewmodels. All you need to do for applyBindings
is give it a single instance of your master view model.
Use this JSFiddle as an example, and try to keep your code structured and organized, or it will get extremely messy very quickly.
// this is like a constructor for your members
var memberViewModel = function memberViewModel(data) {
var self = this;
self.Id = data.MemberId;
self.MemberId = ko.observable(data.MemberId);
self.Name = ko.observable(data.Name);
};
// This is like a constructor for your master view model
var masterViewModel = function() {
var self = this;
self.Members = ko.observableArray();
// put two members into Members
self.Members.push(new memberViewModel({MemberId: 1, Name: 'Member1'}));
self.Members.push(new memberViewModel({MemberId: 2, Name: 'Member2'}));
// set the winner to the first one for default, if you want
self.Winner = ko.observable(self.Members()[0]);
//do your ajax in this function
self.GetNextWinner = function() {
self.Winner(self.Members()[1]);
}
};
//Apply bindings gets one instance of your view model
ko.applyBindings(new masterViewModel());
Upvotes: 4