0

I am using knockout to get and receive an object via JSON. I have got a form that is used to display and edit values that are bound to a Javascript class. My form has got an option for saving and discarding my values. The problem is that if I enter a value to an observed property and click discard the values are not transmitted to the webservice but are saved in my "display form", though, which I do not want. If I click on discard the original values shall be displayed again. Is it possible to perform my value-updating on a button click event (e.g. clicking "save") ? Here a snippet of my current code:

jQuery(document).ready(function(){
    ko.applyBindings(new MyModel());
});

function MyModel(){
   this.Name = ko.observable("Bob");
}

<div data-bind="text: Name"></div>
<input type="text" data-bind="value: Name" />
<input type="button" onclick="discardChanges()" value="Discard" />
<input type="button" onclick="saveChanges()" value="Save" />

If I modified the name and click Discard the original value (in this case Bob) should be restored whereas when I click Save the new value should be assigned (e.g. this.Name("Bill")).

Does anyone have an idea how to solve my problem?

2 Answers2

0

You could simply keep track of the original data:

function MyModel() {
    var self = this;
    self.Name = ko.observable("Bob");
    var orgData = ko.toJS(self);
    self.discardChanges = function() {
        // restore MyModel with the original data (requires the mapping plugin)
        ko.mapping.fromJS(orgData, self); 
    };
}

And:

<input type="button" data-bind="click: discardChanges" value="Discard" />
sroes
  • 14,663
  • 1
  • 53
  • 72
  • Thanks for your advice. Unfortunately it is not working. I am storing my original data in a variable as you described. The values stored are the correct values when I step into the debugger during the discardChanges event. But my modified values are not reset :-( – user3293294 Feb 10 '14 at 16:04
0

Using the ko.extension beneath

var MyModel = function (data) {
    var self = this;

    self.Name= ko.observable('');

    self.Underscore = ko.Underscore(self);

    self.Cancel = function () {
        self.Underscore.Cancel();
    }

    self.Confirm = function () {
        self.Underscore.Confirm();
    }
};

HTML:

 <input type="button" data-bind="click: Cancel" value="Discard" />
 <input type="button" data-bind="click: Confirm" value="Keep" />

This knockout extension, it creates an underscore version of each observable ie self.Name() -> self._Name()

ko.Underscore = function (data) {
    var obj = data;
    var result = {};
    // Underscore Property Check
    var _isOwnProperty = function (isUnderscore, prop) {
        return (isUnderscore == null || prop.startsWith('_') == isUnderscore) && typeof obj[prop] == 'function' && obj.hasOwnProperty(prop) && ko.isObservable(obj[prop]) && !ko.isComputed(obj[prop])
    }
    // Creation of Underscore Properties
    result.init = function () {
        for (var prop in obj) {
            if (_isOwnProperty(null, prop)) {
                var val = obj[prop]();
                var temp = '_' + prop;
                if (obj[prop].isObservableArray)
                    obj[temp] = ko.observableArray(val);
                else
                    obj[temp] = ko.observable(val);
            }
        }
    };
    // Cancel
    result.Cancel = function () {
        for (var prop in obj) {
            if (_isOwnProperty(false, prop)) {
                var val = obj[prop]();
                var p = '_' + prop;
                obj[p](val);
            }
        }
    }
    // Confirm
    result.Confirm = function () {
        for (var prop in obj) {
            if (_isOwnProperty(true, prop)) {
                var val = obj[prop]();
                var p = prop.replace('_', '');
                obj[p](val);
            }
        }
    }
    // Observables
    result.Properties = function () {
        var obs = [];
        for (var prop in obj) {
            if (typeof obj[prop] == 'function' && obj.hasOwnProperty(prop) && ko.isObservable(obj[prop]) && !ko.isComputed(obj[prop])) {
                var val = obj[prop]();
                obs.push({ 'Name': prop, 'Value': val });
            }
        }
        return obs;
    }

    if (obj != null)
        result.init();

    return result;
}
tyler_mitchell
  • 1,727
  • 1
  • 19
  • 27