jmpcm
jmpcm

Reputation: 1852

Mapping a JSON array with knockout.js mapping plugin & and view rendering not working

I'm having a problem mapping a JSON array generated by .NET JavaScriptSerializer, to knockout.js. The array is generated like this (shortened for ease):

OrderProposalFacade[] proposals = new OrderProposalFacade[order.OrderProposals.Count];

foreach (OrderProposal proposal in order.OrderProposals)
{
    proposals[i++] = new OrderProposalFacade(proposal);
}

ViewBag.OrderProposals = new JavaScriptSerializer().Serialize(proposals);

The generated JSON string is something like this:

[{ "ProposalId":1,"ProgrammedWeek":null,
   "ProposalValue":120,"ProposalValueCorrected":130,
   "ProposalDateSent":"01-12-2011","ProposalDateCorrected":"01-12-2011",
   "ServiceId":1,"ServiceDescriptiveId":"OS001","ProposalState":2
 },
 {//another similar object}
]

On the ASP.NET MVC view I do this in order to bind the array:

var initialData = ko.mapping.fromJSON(<%: new HtmlString(ViewBag.OrderProposals as string) %>);
var viewModel = {
    proposals: ko.observableArray(initialData),
    //some methods; removed to ease reading
};
ko.applyBindings(viewModel);

The problem: the proposals array is supposed to be rendered by a knockout.js template, but nothing is rendered. Using Firebug I don't see any objects on the initialData array, so I presume there is an error while initializing it and, therefore, proposals. The binding to the template is like this:

<div id="service-orders" data-bind='template: { name: "proposal-template", foreach: proposals }' style="margin:0 -.7em 0 -0.5em;"></div>

If I remove ko.mapping.fromJSON() everything works fine, i.e., the template is rendered with the values on the proposals array. But another problem arises when I update a value of an object on the initialData array. On my understanding if I update an observable property, the template is rendered again (therefore the knockout.js mapping), but without mapping all properties it won't happen, right?

In short, I need to map all the properties on the initialData array in order to make them observable to update my view when I change a value of one of it's objects, but it isn't working.

Any ideas? Thank you in advance!

Upvotes: 3

Views: 7394

Answers (1)

jmpcm
jmpcm

Reputation: 1852

Finally solved it! The final Javascript is like this:

var initialData = <%: new HtmlString(ViewBag.OrderProposals as string) %>;
var viewModel = {
    proposals: ko.observableArray(),
    //some methods; removed to ease reading
};

viewModel.proposals = ko.mapping.fromJS(initialData);

ko.applyBindings(viewModel);

The 2 changes I made:

  • instead of ko.mapping.fromJSON(initialData) I call ko.mapping.fromJS(initialData). Not shure, but I it seems that .fromJSON() has some problem mapping the array I putted on the question;
  • the .fromJS() method is invoked after the viewModel creation.

Upvotes: 5

Related Questions