2011-09-25 12 views
17

Sto costruendo su RESTFul Store example di ExtJs 4. Mi piacerebbe che il mio script visualizzasse gli errori forniti dal server REST, quando la richiesta Aggiungi o Elimina non riesce. Sono riuscito a ottenere lo stato di successo di una richiesta (vedere il codice seguente), ma come posso raggiungere il messaggio fornito con la risposta?Come ottenere il messaggio di risposta REST in ExtJs 4?

Store:

var store = Ext.create('Ext.data.Store', { 
    model: 'Users', 
    autoLoad: true, 
    autoSync: true, 
    proxy: { 
     type: 'rest', 
     url: 'test.php', 
     reader: { 
      type: 'json', 
      root: 'data', 
      model: 'Users' 
     }, 
     writer: { 
      type: 'json' 
     }, 
     afterRequest: function(request, success) { 
      console.log(success); // either true or false 
     }, 
     listeners: { 
      exception: function(proxy, response, options) { 

       // response contains responseText, which has the message 
       // but in unparsed Json (see below) - so I think 
       // there should be a better way to reach it than 
       // parse it myself 

       console.log(proxy, response, options); 
      } 
     } 
    } 
}); 

tipica risposta REST:

"{"success":false,"data":"","message":"VERBOSE ERROR"}" 

Forse lo sto facendo tutto sbagliato, quindi ogni consiglio è apprezzato.

risposta

25

Suppongo che il servizio segua il principio REST e utilizzi i codici di stato HTTP diversi da 2xx per le operazioni non riuscite. Tuttavia, Ext non analizza il corpo della risposta per le risposte che non restituiscono lo stato OK 2xx. Cosa l'oggetto eccezione/risposta (passato ai listener di eventi 'eccezione') fa fornisce in questi casi solo il messaggio di stato HTTP in response.statusText.

Quindi sarà necessario analizzare il responseText in JSON. Quale non è realmente un problema poiché può essere compiuto con una singola linea.

var data = Ext.decode(response.responseText); 

A seconda del vostro stile di codifica si potrebbe anche voler aggiungere un po 'la gestione degli errori e/o di distinguere tra 'previsto' e codici di stato di errore 'inaspettato' HTTP. (Questo è da Ext.data.reader.Json)

getResponseData: function(response) { 
    try { 
     var data = Ext.decode(response.responseText); 
    } 
    catch (ex) { 
     Ext.Error.raise({ 
      response: response, 
      json: response.responseText, 
      parseError: ex, 
      msg: 'Unable to parse the JSON returned by the server: ' + ex.toString() 
     }); 
    } 

    return data; 
}, 

La ragione di questo comportamento è probabilmente a causa della classe RIPOSO proxy non essendo un membro prima classe nel pacchetto di dati. È derivato da una classe base comune che definisce anche il comportamento del proxy standard AJAX (o JsonP) che utilizza i codici di stato HTTP solo per gli errori del canale di comunicazione. Quindi non si aspettano alcun messaggio analizzabile dal server in questi casi. Le risposte del server che indicano gli errori dell'applicazione devono invece essere restituite con lo stato HTTP OK e una risposta JSON come postata nella domanda (con success:"false" e message:"[your error message]").

È interessante notare che un server REST può restituire una risposta con stato non 2xx e un corpo risposta con una risposta JSON valida (in termini Ext) e la proprietà success impostata su "true". L'evento di eccezione verrebbe comunque attivato e il corpo della risposta non analizzato. Questa configurazione non ha molto senso - voglio solo sottolineare la differenza tra "successo" in termini di codice di stato HTTP rispetto alla proprietà di successo nel corpo (con il primo che ha la precedenza su quest'ultimo).

Aggiornamento

Per una soluzione più trasparente si potrebbe estendere (o sostituire) Ext.data.proxy.Rest: questo cambierà il valore successo da false a true e quindi chiamare l'implementazione processResponse standard. Questo emulerà il comportamento 'standard' Ext e analizzerà il responseText. Ovviamente ci si aspetta una risposta JSON standard come delineata nel tuo post originale con success:"false" (o altrimenti non riuscita). Questo non è tuttavia verificato e l'espressione if dovrebbe probabilmente essere più intelligente.

Ext.define('Ext.ux.data.proxy.Rest', { 
    extend: 'Ext.data.proxy.Rest', 

    processResponse: function(success, operation, request, response, callback, scope){ 
     if(!success && typeof response.responseText === 'string') { // we could do a regex match here 
      var args = Array.prototype.slice.call(arguments); 
      args[0] = true; 
      this.callParent(args); 
     } else { 
      this.callParent(arguments); 
     } 
    } 
}) 
+0

Super!Funziona perfettamente, grazie per la spiegazione dettagliata! :-D – Dae

+0

Alla fine ho rinunciato a REST in favore dell'API Ajax semplice. Ecco il mio codice finale per l'elaborazione del messaggio di risposta: http://pastie.org/2657317 – Dae

+0

Man questa è un'ottima spiegazione ... Sencha deve aggiungere questo ai propri documenti! – HDave

Problemi correlati