Reputation: 14596
I use mapping plugin for creating the view model. Here's the watcher output from Chrome:
viewModel: Object
Id: function observable()
Language: function observable()
QuoteListViewModel: Object
QuoteSelectedViewModel: Object
The MVC Model is :
public class QuoteRequestViewModel
{
public Guid Id { get; set; }
public LanguageEnum Language { get; set; }
public QuoteViewModel QuoteSelectedViewModel { get; set; }
public QuoteListViewModel QuoteListViewModel { get; set; }
}
The QuoteViewModel is :
public class QuoteViewModel
{
public string ProductName { get; set; }
public decimal MonthPrice { get; set; }
public decimal QuarterPrice { get; set; }
public decimal BiannualPrice { get; set; }
public decimal YearPrice { get; set; }
public List<CoverQuoteViewModel> CoverQuotesViewModel { get; set; }
}
The QuoteListViewModel is not relevant here and actually works fine.
Two questions:
1) Why is QuoteSelectedViewModel mapped as an Object instead of an Observable function ? I understand why it's the case for QuoteListViewModel because it's an Array, but QuoteSelectedViewModel is not an Array.
2) I can't bind my DOM to QuoteSelectedViewModel. Here's what I do:
viewModel.customizeQuote = function () {
viewModel.QuoteSelectedViewModel = this;
}
and customizeQuote is called there:
<table data-bind="with: QuoteListViewModel">
<tbody>
<tr data-bind="foreach: Quotes">
<td>
<a class="btn btn-primary" href="#" data-bind="click: $root.customizeQuote">Customize</a>
</td>
</tr>
When debugging, I can see that QuoteSelectedViewModel contains the correct Quote from the QuoteListViewModel Array. However doing:
viewModel.QuoteSelectedViewModel = this;
seems incorrect to me. It should be an observable and I should do
viewModel.QuoteSelectedViewModel( this );
Any idea what's wrong ?
[EDIT]
The fact that QuoteSelectedViewModel is not observable is obviously the root of the problem.
I've added the following code:
viewModel.SelectedQuote = ko.observable(viewModel.QuoteSelectedViewModel);
and in the customize method I do this instead:
viewModel.SelectedQuote(this);
So now, the list is bound. So how do I make the QuoteSelectedViewModel an observable object right from the beginning when I use the mapping plugin ?
Upvotes: 0
Views: 120
Reputation: 114792
The mapping plugin creates observables for the lowest level properties and arrays. For nested objects it does not make the parent an observable.
var test = {
sub: {
name: "Bob"
}
};
In this case, it will make name
an observable, but sub
will not be observable.
One option is to customize how objects are created using the mapping options, as described here.
Upvotes: 1