Redo - Undo functionality using angular js for large data

前端 未结 1 1839
借酒劲吻你
借酒劲吻你 2021-01-26 05:50

Currently i\'m creating a table dynamically, in that multiple rows get added dynamically (Similar to Excel).Table can have millions of rows.

For redo/undo functionality

相关标签:
1条回答
  • 2021-01-26 06:12

    To summarise, you can add state management with a Memento Factory.

    All the code you need is below, but there's a little more background on my blog: AngularJS Memento Factory.

    function MementoFactory(){
      return function() {
        var memento = this;
        // Private properties
        var subjects = arguments; // We can track multiple objects or arrays
        var stack = []; // Each call to "save" makes a copy of every subject on the stack
        var currentIndex = 0; // The "current" position on the stack stack
        // Begin by saving the current state
        save();
        // Public properties
        memento.timestamp = null; // The timestamp for the current stack
        // Public methods
        memento.save = save;
        memento.canUndo = canUndo;
        memento.undo = undo;
        memento.canRedo = canRedo;
        memento.redo = redo;
    
        function save() {
          var snapshot = {
            timestamp: Date.now(), // The save time
            subjects: [], // Contains each of the subjects
          };
          for (var a = 0, al = subjects.length; a < al; a++) {
            snapshot.subjects.push(angular.copy(subjects[a]));
          }
          if (stack[currentIndex] && angular.equals(stack[currentIndex].subjects, snapshot.subjects)) {
            return; // Do nothing if the new snapshot is the same as the current snapshot
          }
          if (canRedo()) {
            stack = stack.slice(0, currentIndex + 1); // Since we can "redo" we must overwrite that timeline (consider Back To The Future: Part II)
          }
          memento.timestamp = snapshot.timestamp; // Store the time
          stack.push(snapshot);
          currentIndex = stack.length - 1;
        };
        function canUndo() {
          return currentIndex > 0;
        };
        function undo() {
          if (canUndo()) {
            restoreSnapshot(-1);
          }
        };
        function canRedo() {
          return currentIndex < stack.length - 1;
        };
        function redo() {
          if (canRedo()) {
            restoreSnapshot(+1);
          }
        };
        function restoreSnapshot(indexDiff) {
          currentIndex += indexDiff;
          var snapshot = stack[currentIndex];
          memento.timestamp = snapshot.timestamp; // Update the timestamp
          for (var s = 0, sl = snapshot.subjects.length; s < sl; s++) {
            if (snapshot.subjects[s] !== subjects[s]) {
              angular.copy(snapshot.subjects[s], subjects[s]);
            }
          }
        };
      };
    };
    
    angular
      .module('app')
      .factory('Memento', MementoFactory);
    

    Create a new Memento(...) object, passing the non-primitive variables you want to track

    ctrl.user = { name: 'David King', location: 'England' };
    ctrl.tags = [ 'AngularJS', 'Angular', 'Firebase' ];
    // Create a new Memento object
    var memento = new Memento(ctrl.user, ctrl.tags);
    // Expose the undo and redo methods
    ctrl.canUndo = memento.canUndo;
    ctrl.redo    = memento.redo;
    ctrl.canRedo = memento.canRedo;
    ctrl.undo    = memento.undo;
    

    Add undo and redo buttons to your View

    <button
      type="button"
      ng-click="ctrl.undo()"
      ng-disabled="!ctrl.canUndo">Undo</button>
    <button
      type="button"
      ng-click="ctrl.redo()"
      ng-disabled="!ctrl.canRedo">Redo</button>
    

    Save your Memento object, when appropriate

    <input
      type="text"
      ng-model="ctrl.user.name"
      ng-change="ctrl.save()">
    <input
      type="text"
      ng-model="ctrl.user.location"
      ng-change="ctrl.save()">
    

    ... and that’s it!

    0 讨论(0)
提交回复
热议问题