Memento en Javascript
-
22-08-2019 - |
Pregunta
Estoy buscando una implementación de JavaScript del patrón memento (GOF) para ser utilizado en formas CRUD. En su nivel más básico será suficiente para deshacer los cambios en las entradas, pero sería ideal para usar con marcos estándar JS como YUI o Ext, para deshacer y rehacer acciones de la red (nueva fila, eliminar la fila, etc.).
Gracias
Solución
Dado que no estoy viendo ningún ejemplo de código, aquí es un rápido 'n sucia implementación de deshacer para una forma EXT:
var FormChangeHistory = function(){
this.commands = [];
this.index=-1;
}
FormChangeHistory.prototype.add = function(field, newValue, oldValue){
//remove after current
if (this.index > -1 ) {
this.commands = this.commands.slice(0,this.index+1)
} else {
this.commands = []
}
//add the new command
this.commands.push({
field:field,
before:oldValue,
after:newValue
})
++this.index
}
FormChangeHistory.prototype.undo = function(){
if (this.index == -1) return;
var c = this.commands[this.index];
c.field.setValue(c.before);
--this.index
}
FormChangeHistory.prototype.redo = function(){
if (this.index +1 == this.commands.length) return;
++this.index
var c = this.commands[this.index];
c.field.setValue(c.after);
}
Ext.onReady(function(){
new Ext.Viewport({
layout:"fit",
items:[{
xtype:"form",
id:"test_form",
frame:true,
changeHistory:new FormChangeHistory("test_form"),
defaults:{
listeners:{
change:function( field, newValue, oldValue){
var form = Ext.getCmp("test_form")
form.changeHistory.add(field, newValue, oldValue)
}
}
},
items:[{
fieldLabel:"type some stuff",
xtype:"textfield"
},{
fieldLabel:"then click in here",
xtype:"textfield"
}],
buttons:[{
text:"Undo",
handler:function(){
var form = Ext.getCmp("test_form")
form.changeHistory.undo();
}
},{
text:"Redo",
handler:function(){
var form = Ext.getCmp("test_form")
form.changeHistory.redo();
}
}]
}]
})
});
La implementación de este para una rejilla editable es un poco más difícil, pero usted debería ser capaz de hacer una GridChangeHistory que hace lo mismo y luego llamar a la función add () del oyente AfterEdit de EditorGrid.
El "antes" y "después" de las propiedades podrían ser llamadas de retorno que le permiten deshacer / rehacer cualquier tipo de mando, pero eso requeriría más trabajo cuando se llama a añadir ()
Otros consejos
Dado que usted está tratando de deshacer / rehacer comandos, se sugiere emplear la href="http://en.wikipedia.org/wiki/Command_pattern" rel="nofollow noreferrer"> patrón vez . Aquí hay un enlace a un tutorial ; es en C #, pero debe ser lo suficientemente fácil de seguir para un programador OO.