You have several issues. Here's my 2 cts.
Not a biggie, but it's clearer if you could structure your data in a way that the top-level isn't the array itself, but an object with that array, e.g. { items: [/* original data here*/] }
.
With the MVVM pattern it's best not to put logic in your view, and text: FromUnixTs(date_time())
borders that. Instead, put all that logic on your view model and just have a text: UnixTx
binding. This also works around the problematic code in your question surrounding the prototype
stuff.
If you want to augment view models created with the mapping plugin, you can do so by creating mapping options that allow you to tweak the model upon creation.
Finally, a problem that prevents others from helping you: your question contains irrelevant code (the jQuery ajax stuff) making it harder to understand things, and the examples are incomplete and invalid snippets (unclosed tags, etc). In addition, you ask many questions in one, creating a very large question (almost a review request) which SO users tend to shy away from.
If I put all this together (at least 1-3), then I'd suggest a different approach like the following. Update your View to this:
<table>
<tbody data-bind="foreach: items">
<tr class="gv">
<td data-bind="text: id"></td>
<td data-bind="text: number"></td>
<td data-bind="text: unixTs"></td>
</tr>
</tbody>
</table>
No logic there.
Then, assuming the following data:
var data = {
items: [{id: 1, number: 42, date_time: 1375948769449},
{id: 2, number: 106, date_time: 1375948769349}]
};
I'd construct the view model using the mapping plugin like this:
var mapping = {
'items': {
create: function (item) {
return new ItemViewModel(item.data);
}
}
};
var viewModel = ko.mapping.fromJS(data, mapping, {});
This uses an ItemViewModel
constructor function that augments the mapped VM with the unixTs
observable:
var ItemViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
this.unixTs = ko.computed(function () {
var date = new Date(self.date_time());
var hours = date.getHours();
var minutes = date.getMinutes();
var seconds = date.getSeconds();
return hours + ':' + minutes + ':' + seconds;
});
};
You can see all this at work in this fiddle. Hope this helps.
If you can't change the structure of the data from the server, you can still use the augmented view model version. With a few changes:
// Data not augmented, just the raw array OP gets from the service
var data = [{id: 1,number: 42,date_time: 1375948769449},
{id: 2,number: 106,date_time: 1375948769349}];
// Augment the data into an object to make a clearer view model:
var viewModel = ko.mapping.fromJS({items: data}, mapping, {});
See this fiddle.