Using Knockoutjs Mapping Plugin inside viewmodel constructor

276 views Asked by At

I am trying to use the mapping plugin inside the constructor so I can easily add other functions to the constructor and have the observable items automatically created from the mapping plugin. Here is the code that I currently have but it is neither mapping the observable variables that I provide it or including the 'save' function in the end viewmodel. Is there a better way to do this?

function ViewModel(model){
        var self = this;

        self = ko.mapping.fromJS(model);

        self.save = function() {
            var data = ko.toJSON(self);
            $.post("/Licensing/edit", data, function(returnedData) {
                // This callback is executed if the post was successful
            });
        }

    };

    var vm = new ViewModel(model);
    ko.applyBindings(vm);
3

There are 3 answers

1
nemesv On BEST ANSWER

Your code is not working because ko.mapping.fromJS(model); returns a new object what you assign to your self local variable what you extend with the save function.

However this new object is not returned from your constructor function so you will end with with an empty object because not the originally passed in this is modified.

You can fix this with returning self from your constructor:

function ViewModel(model){
    var self = this;

    self = ko.mapping.fromJS(model);

    self.save = function() {
        var data = ko.toJSON(self);
        $.post("/Licensing/edit", data, function(returnedData) {
            // This callback is executed if the post was successful
        });
    }

    return self;
};

Or you can tell the mapping plugin to don't create a new object just use the currently created one with passing self as the third argument:

function ViewModel(model){
    var self = this;

    ko.mapping.fromJS(model, {}, self);

    self.save = function() {
        var data = ko.toJSON(self);
        $.post("/Licensing/edit", data, function(returnedData) {
            // This callback is executed if the post was successful
        });
    }

};
0
Roy J On

There is no reason to use a constructor (using new). You're not going to make multiple instances or have a prototype. Just use the object ko.mapping creates for you.

function ViewModel(model){
    var self = ko.mapping.fromJS(model);

    self.save = function() {
        var data = ko.toJSON(self);
        $.post("/Licensing/edit", data, function(returnedData) {
            // This callback is executed if the post was successful
        });
    }
    return self;
};

var vm = ViewModel(model);
ko.applyBindings(vm);
0
Yvan On

Also save is an private method, write save like that :

self._save = function() { }