2011-10-24 11 views
9

sto usando ExtJS 4 e hanno un Ext.data.Store con un proxy Ajax e api:Annulla store.remove dopo la chiamata del server in 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 
       }); 
      } 
     } 
    ... 

Quando uso la funzione di aggiornamento e il mio server restituisce un oggetto json con success:false (perché ha inserito qualcosa di sbagliato) il campo nella mia griglia associata è ancora contrassegnato come modificato e l'utente ha la possibilità di cambiare il suo valore errato.

Ciò funziona correttamente.

Ma quando ho rimuovere un record dal negozio ...

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

... poi ExtJS rimuove questo record dal negozio prima e chiamare l'API Ajax dopo. Quindi, quando la destroy api restituisce success:false, il messaggio viene visualizzato come eccezione come nell'API di aggiornamento, ma va bene, ma il mio record è stato rimosso dallo store! Ad esempio l'eccezione del server dice che non è possibile rimuovere questo record a causa di qualsiasi cosa ma è già stato rimosso nell'archivio.

Come annullare la rimozione del negozio dopo la sincronizzazione del server? Voglio che il record rimanga nel negozio se il server restituisce success:false.

Qualche idea? Forse un bug?


UPDATE SOLUZIONE

Sulla base di Anwer di Ryan, ho modificato l'ascoltatore eccezione, come segue, che funziona molto bene:

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

Probabilmente un bug, o necessità di scavare nel codice sorgente per vedere cosa succede. Hmm. Domanda interessante Ho visto questo prima, ma ho superato questo ricaricando il negozio. Inefficiente, ma va bene per i dati di piccole dimensioni. –

+3

Bello :) Ma hai dimenticato di aggiungere 'gridStore.removed = []' else se rimuovi l'elemento avrai duplicati (quindi è ancora nell'array rimosso) – VDP

risposta

5

Basta estendere il codice che ha dato, in particolare il listeners area:

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

Grazie mille, è il modo corretto. Ho modificato la tua soluzione un po ', ho dato un'occhiata alle mie domande aggiornate, perché se aggiungi solo i record, questi vengono aggiunti alla fine dell'elenco, ma dovrebbero rimanere dove erano stati prima. – Marc

2

Sto usando model.destroy, questo è quello che io uso per l'eliminazione di voci singolari dalla rete:

   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

bello. adatto solo per registrazione singola. –

6

tecnica L'inserto non ha funzionato per me, il record rimosso rimane marcato per la rimozione sulla prossima operazione di sincronizzazione. Sto usando Ext.data.Store.rejectChanges() per questo scopo.

+0

Questo non è un metodo predefinito è? Hai usato [questa implementazione] (http://www.sencha.com/forum/showthread.php?141982-commitChanges-and-rejectChanges-for-the-Store-in-ExtJS-4)? – VDP

+0

Questo metodo esiste in ExtJS 4.1.1a. Non sono sicuro della versione 4.0 o delle versioni intermedie.Questa dovrebbe essere la risposta corretta. –

2

Utilizzo le funzioni di callback "success", "failure" o "callback" durante la sincronizzazione. Spero che questo metodo possa aiutarti.

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