Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

knockout create an empty object from auto-mapped observable

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 :/

like image 671
Tallmaris Avatar asked May 26 '12 02:05

Tallmaris


People also ask

How do you get the Knockout value from observable?

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 .

How do you empty an observable array?

To clear an observableArray you can set the value equal to an empty array.

What is Ko observable ()?

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.

How do you declare a ViewModel property as observable?

You just need to declare ViewModel property with function ko. observable() to make it Observable.


1 Answers

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.

like image 187
madcapnmckay Avatar answered Nov 09 '22 02:11

madcapnmckay