2011-10-24 14 views
9

estoy usando ExtJS 4 y tienen un Ext.data.Store con un proxy Ajax y api:Cancelar store.remove después de la llamada del servidor en ExtJS 4

var gridStore = Ext.create('Ext.data.Store', { 
    autoSync: true, 
    proxy: { 
     type: 'ajax', 
     api: { 
      read: 'myurl', 
      create: 'myurl', 
      update: 'myurl', 
      destroy: 'myurl' 
     }, 
     reader: { 
      type: 'json', 
      successProperty: 'success', 
      root: 'data', 
      messageProperty: 'message' 
     }, 
     writer: { 
      type: 'json', 
      writeAllFields: false, 
      root: 'data' 
     }, 
     listeners: { 
      exception: function(proxy, response, operation){ 
       Ext.MessageBox.show({ 
        title: 'Server error', 
        msg: operation.getError(), 
        icon: Ext.MessageBox.ERROR, 
        buttons: Ext.Msg.OK 
       }); 
      } 
     } 
    ... 

Cuando utilizo la función de actualización y mi servidor devuelve un objeto json con success:false (porque ingresó algo incorrecto) el campo en mi cuadrícula asociada todavía se marca como cambiado y el usuario tiene la opción de cambiar su valor incorrecto.

Eso funciona bien.

Pero cuando quito un registro de la tienda de ...

var store = Ext.StoreManager.lookup('gridStore'); 
store.remove(store.getById(id)); 

... entonces ExtJS elimina este registro de la tienda de primero y llamar a la API Ajax después. Entonces, cuando la API de destrucción devuelve success:false, el mensaje se muestra como una excepción, como en la API de actualización, eso está bien, ¡pero mi registro se ha eliminado de la tienda! Como ejemplo, la excepción del servidor dice que no se puede eliminar este registro debido a lo que sea, pero que ya se eliminó en la tienda.

Cómo cancelar la eliminación de la tienda después de la sincronización del servidor? Quiero que el registro permanezca en la tienda si el servidor devuelve success:false.

¿Alguna idea? Tal vez un error?


ACTUALIZACIÓN SOLUCIÓN

Basado en anwer de Ryan, he modificado el oyente excepción de la siguiente manera, que funciona muy bien:

listeners: { 
    exception: function(proxy, response, operation){ 
     Ext.MessageBox.show(...); 
     // get the removed records and insert them where they have been 
     var removedRecords = gridStore.getRemovedRecords(); 
     for(var i=0; i<removedRecords.length; i++){ 
      var record = removedRecords[i]; 
      gridStore.insert(record.index, record); 
     } 
    } 
} 
+0

Probablemente es un error, o necesita profundizar en el código fuente para ver qué pasa. Hmm. Interesante pregunta. Vi esto antes, pero supero esto volviendo a cargar la tienda. Ineficiente pero está bien para datos pequeños. –

+3

Agradable :) Pero olvidó agregar 'gridStore.removed = []' else si elimina ese elemento nuevamente tendrá duplicados (aún está en la matriz eliminada) – VDP

Respuesta

5

Sólo extender el código que le dio, en concreto el listeners área:

listeners: { 
     exception: function(proxy, response, operation){ 
      Ext.MessageBox.show({ 
       title: 'Server error', 
       msg: operation.getError(), 
       icon: Ext.MessageBox.ERROR, 
       buttons: Ext.Msg.OK 
      }); 
      gridStore.add(gridStore.getRemovedRecords()); 
     } 
    } 
+0

Muchas gracias, esa es la manera correcta. Cambié tu solución un poco, eche un vistazo a mis preguntas actualizadas, porque si solo agregas los registros, se agregarán al final de la lista, pero deberían permanecer donde estuvieron antes. – Marc

2

estoy usando model.destroy, esto es lo que yo uso para la eliminación de entradas singulares de la cuadrícula:

   text : 'Delete', 
       itemId : 'delete', 
       scope : this, 
       handler : function() { 
        var selection = grid.getView().getSelectionModel().getSelection()[0]; 
        if(selection) { 
         selection.destroy({ 
          failure : function() { 
           console.log('Record could not be deleted.'); 
          }, 
          success : function() { 
           store.remove(selection); 
           console.log('Record successfuly removed.'); 
          }, 

         }); 
        } 
       } 
+0

agradable. adecuado para solo registro único. –

6

técnica El inserto no funcionó para mí, el registro eliminado permanece marcada para la eliminación en la siguiente operación de sincronización. Estoy usando Ext.data.Store.rejectChanges() para este propósito.

+0

Ese no es un método predeterminado, ¿verdad? ¿Usó [esta implementación] (http://www.sencha.com/forum/showthread.php?141982-commitChanges-and-rejectChanges-for-the-Store-in-ExtJS-4)? – VDP

+0

Ese método existe en ExtJS 4.1.1a. No estoy seguro acerca de 4.0 o versiones en el medio.Esta debería ser la respuesta correcta. –

2

Estoy utilizando funciones de devolución de llamada 'éxito', 'falla' o 'devolución de llamada' cuando se sincroniza. Espero que este método pueda ayudarlo.

store.remove(records); 
store.sync({ 
    success: function (proxy, operations) { 
     // pop success message 
    }, failure: function (proxy, operations) { 
     // resume records 
     store.rejectChanges(); 
    } 
}); 
Cuestiones relacionadas