Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undo Redo In Angular JS

I have a big object lined in $rootScope (say > 100 objects and each having hierarchy of objects/array again), I want to $watch entire $rootScope with deepWatching(i.e. turning 3rd parameter of $watch to TRUE).

But the problem here is, $watch returns 2 objects (i.e. one Old RootScope and Modified RootScope). Then I have to do a process of checking what attribute of object changed in $rootScope and its hierarchy to PUSH it into stack.

Do we have an easy way out to get the exact attribute changed while watching a $scope?

$scope.$watch($rootScope, function(oldObj, newObj){

   //all I want here is exactly what attribute changed, NOT entire objects!

}, true);

Alternatively, I could add watch on each attribute of the Object but it appears to be extremely expensive.

What is the best way to achieve undo/redo in angular js?

Note :-

  1. angular-history doesnt suit my need because I want to watch all attributes of object, which may also contain other objects and array.

  2. I'm certain watching entire $rootScope is not a good idea either, but I have aimed to build an UI which has several grids, drag n drop, might contain form, elements can be deleted. So I want to build an overall solution to stack the changes and undo it on CTRL + Z. Imagine replicating desktop version of Photoshop.

like image 848
Libu Avatar asked Nov 06 '13 16:11

Libu


People also ask

How do you implement redo undo?

If “UNDO” string is encountered, pop the top element from Undo stack and push it to Redo stack. If “REDO” string is encountered, pop the top element of Redo stack and push it into the Undo stack. If “READ” string is encountered, print all the elements of the Undo stack in reverse order.

What is undo and redo features?

To redo an undone action, press Ctrl + Y. The Undo and Redo features let you remove or repeat single or multiple typing actions, but all actions must be undone or redone in the order you did or undid them – you can't skip actions.

How do you undo in Javascript?

If the user wants to undo, you simply pop the last memento and apply it. The program returns to the state it was before the last action was applied.

How do you redo in HTML?

To reverse your last action, press CTRL+Z. You can reverse more than one action. To reverse your last Undo, press CTRL+Y.


2 Answers

Undo/redo is based on the command pattern. And yes, there will be a lot of watches; such a rich functionality does not come cheap.

Just for the fun of it, here is a simple (but quite usable and extensible) implementation: http://jsfiddle.net/sYc4e/1/

A command is an interface for objects that know how to apply and rollback a change:

function XxxCommand() {
    // implementation specific
}
Command.prototype.execute = function() {
    // implementation specific
};
Command.prototype.rollback = function() {
    // implementation specific
};

Usage: You decorate the <input>s with a directive:

<input name="name" undoable ng-model="data.name" />

And wrap them with an element (e.g. the <form>) with the undo-support directive:

<form undo-support>

The link function of undoable listens for a change in the <input> and registers a command with the undoableSupport. The controller of undoableSupport keeps track of the command list.

like image 72
Nikos Paraskevopoulos Avatar answered Oct 10 '22 10:10

Nikos Paraskevopoulos


There's also an undo/redo library called Angular-Chronicle. For myself at least, it was a better option than angular-history.

like image 39
Zambezi Avatar answered Oct 10 '22 11:10

Zambezi