JS knockout initializes an observable array from server data using javascript type

I am looking for the best way to initialize the observed array by knockout from some server data (ViewBag), and I want the contents of the array to be of the javascript type that I defined. Without a JS type requirement, I could simply use:

materialVarieties: ko.observableArray(@Html.Raw(Json.Encode(ViewBag.Materials))) 

but I also have the type of JS material that I want to use, so I can have some additional properties and functions of the ViewModel, for example:

 var material = function(id, name) { this.id = id; this.name = name; this.selected = ko.observable(false); this.select = function() { jQuery.each(processViewModel.materials(), function(index, item) { item.selected(false); }); this.selected(true); } } 

And then the required initialization will look like this:

 materialVarieties: ko.observableArray([new material(1, "Apricot"), ..... 

I am currently creating a row from ViewBag data and then rendering it as an initializer as follows:

 @{ var items = string.Join(",", ((IEnumerable<MaterialVariety>) ViewBag.Materials) .Select(m => string.Format("new material({0}, {1})", Json.Encode(m.Id), Json.Encode(m.Name)))); } var processViewModel = { material: ko.observableArray([@Html.Raw(items)]) 

But I am wondering if there is a cleaner path than the string.Join bit. I could wrap him in an assistant. What are you doing?

+8
javascript asp.net-mvc asp.net-mvc-3
source share
1 answer

Usually I first serialize the array and then map it by putting it in the view model. It would be like this:

 var originalVarieties = @Html.Raw(Json.Encode(ViewBag.Materials)) var processViewModel = { materialVarieties: ko.observableArray(ko.utils.arrayMap(originalVarieties, function(variety) { return new material(variety.id, variety.name); })) } 

It requires a little extra processing on the client side, but seems cleaner than string strings.

+15
source share

All Articles