I am trying to solve a small problem with ko mapping. The scenario is that my ViewModel is basically a collection of objects. Each of the objects is created from a json call, in this way:
var ViewModel = ko.observableArray();
$.getJSON(url, function(data) {
ViewModel.push(ko.mapping.fromJSON(data));
});
This works perfectly and I can do all sort of magic in my HTML. The question is if for example I want to add something to my collection, let's say to support client-side "Add and Edit" scenario. I would like to do something like:
<input type="button" value="add new" data-bind="click: AddNew" />
And I would like the AddNew function in the ViewModel to be something like:
function AddNew() {
this.push(// WHAT HERE?);
}
Basically I need to push an object which is identical to the other already existing, but of course with all blanked out properties...
I was thinking of a way of "cloning" an object form the list and setting all the observables to empty but I would not know where to start I'm afraid :/
To read the observable's current value, just call the observable with no parameters. In this example, myViewModel. personName() will return 'Bob' , and myViewModel. personAge() will return 123 .
To clear an observableArray you can set the value equal to an empty array.
An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted. The main advantage of KO is that it updates our UI automatically when the view model changes.
You just need to declare ViewModel property with function ko. observable() to make it Observable.
If you are going to expand your functionality to client-side edit/add then i would recommend formalizing your objects into a js class and then mapping these objects internally. This would allow you to have your add methods on your main viewmodel and create blank instances client side easily.
One caveat with the mapping plugin is that for updating objects it expects those objects to have been originally mapped by the plugin. Here's a quick example of how it could be done.
var YourObjectClass = function (config) {
var self = this, data;
// your default structure goes here
data = $.extend({
name: "",
id : -1
}, config);
ko.mapping.fromJS(data, {}, self);
};
var viewModel = function(initialData) {
var self = this;
ko.mapping.fromJS(initialData, {
items: {
create : function (options) {
return new YourObjectClass(options.data);
}
}
}, self);
this.AddNew = function () {
self.items.push(new YourObjectClass());
}
};
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With