简体   繁体   中英

Knockout Js binding to an edit modal with an undo feature

I am using ko.js to display a table of venues.

Each venue has an edit button that brings up a dialog showing the editable data.

When the edit button is pressed I bind the venue to the dialog and I store a copy of the data in an undo object.

When I edit fields on the dialog, both the dialog and table are updated.

When I cancel the edit, I bind the venue to the undo objects state. This updates the dialog but it does not update on the table.

Any idea what I am doing wrong here?

Here is my view model.

VenueViewModel = function(venues) {
    var self = this;

    var venueModal = $("#venueModal");
    this.venues = ko.mapping.fromJS(venues);
    this.venue = ko.observable();
    this.venueUndo = null;

    //Cancel an edit                
    this.cancel = function() {
        self.venue(ko.mapping.fromJS(self.venueUndo));
        venueModal.modal("hide");
    }

    //Edit an existing venue
    this.edit = function(venue) {
        self.venue(venue);
        self.venueUndo = ko.mapping.toJS(venue);
        venueModal.modal("show");
    };

    //Create a new venue
    this.create = function() {
        self.venue(new Venue());
        venueModal.modal("show");
    };
};

ko.applyBindings(new VenueViewModel(venues));

The article nemesv linked in his comment was the answer.

http://www.knockmeout.net/2013/01/simple-editor-pattern-knockout-js.html

You might consider using KO-UndoManager for this. Here's a sample code to register your viewmodel:

VenueViewModel.undoMgr = ko.undoManager(VenueViewModel, {
  levels: 12,
  undoLabel: "Undo (#COUNT#)",
  redoLabel: "Redo"
});

You can then add undo/redo buttons in your html as follows:

 <div class="row center-block">
    <button class="btn btn-primary" data-bind="
      click: undoMgr.undoCommand.execute, 
      text: undoMgr.undoCommand.name, 
      css: { disabled: !undoMgr.undoCommand.enabled() }">UNDO</button>
    <button class="btn btn-primary" data-bind="
      click: undoMgr.redoCommand.execute, 
      text: undoMgr.redoCommand.name, 
      css: { disabled: !undoMgr.redoCommand.enabled() }">REDO</button>
  </div> 

And here 'sa Plunkr showing it in action.

您可以这样设置淘汰赛可观察对象:

self.venue(ko.mapping.fromJS(self.venueUndo));

We Have a small extension to Knockout.js as part out project that extends observables so they can be registered to different stacks of there history.

Maybe it can help you.

Knockout-Memento

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM