2011-09-25 14 views
17

Estoy construyendo sobre RESTFul Store example de ExtJs 4. Me gustaría que mi script muestre los errores provistos por el servidor REST, cuando la solicitud Agregar o Eliminar falla. Logré obtener el estado de éxito de una solicitud (ver el código a continuación), pero ¿cómo llego al mensaje proporcionado con la respuesta?¿Cómo obtener el mensaje de respuesta REST en ExtJs 4?

tienda:

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); 
      } 
     } 
    } 
}); 

típica respuesta RESTO:

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

Tal vez estoy haciendo todo mal, por lo que cualquier consejo se agradece.

Respuesta

25

que suponer que su servicio sigue el principio REST y utiliza los códigos de estado HTTP que no sean 2xx para operaciones sin éxito. Sin embargo, Ext va a no analiza el cuerpo de respuesta para las respuestas que no devuelven el estado OK 2xx. Lo que el /objeto respuesta de excepción (que se pasa a los detectores de eventos 'excepción') hace proporcionan en estos casos es sólo el mensaje de estado HTTP en response.statusText.

Por lo tanto, tendrá que analizar el texto de respuesta a JSON usted mismo. Lo cual no es realmente un problema, ya que se puede lograr con una sola línea.

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

Dependiendo de su estilo de codificación también puede ser que desee añadir un poco de manejo de errores y/o distinguir entre los códigos de estado HTTP Error inesperado '' 'espera' y. (Esto es de 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 razón de este comportamiento es debido probablemente a la clase RESTO proxy no ser un miembro de la primera clase en el paquete de datos. Se deriva de una clase base común que también define el comportamiento del proxy AJAX estándar (o JsonP) que usa códigos de estado HTTP solo para errores del canal de comunicación. Por lo tanto, no esperan ningún mensaje analizable del servidor en tales casos. Se espera que las respuestas del servidor que indican errores de aplicación se devuelvan con el estado HTTP OK, y una respuesta JSON como se publicó en su pregunta (con success:"false" y message:"[your error message]").

Curiosamente, un servidor REST podría devolver una respuesta con un estado que no sea 2xx y un cuerpo de respuesta con una respuesta JSON válida (en términos Ext) y la propiedad de éxito establecida en 'verdadera'. El evento de excepción aún se disparará y el cuerpo de la respuesta no se analizará. Esta configuración no tiene mucho sentido. Solo quiero señalar la diferencia entre el "éxito" en términos de código de estado HTTP en comparación con la propiedad de éxito en el cuerpo (el primero tiene prioridad sobre el último).

actualización

Para una solución más transparente que podría extender (o anular) Ext.data.proxy.Rest: Esto cambiará el valor del éxito false a true y luego llamar a la aplicación processResponse estándar. Esto emulará el comportamiento Ext "estándar" y analizará el texto de respuesta. Por supuesto, esto esperará una respuesta JSON estándar como se describe en su publicación original con success:"false" (o de lo contrario fallará). Esto no se ha probado, y la expresión if probablemente sea más inteligente.

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!Funciona perfectamente, gracias por la explicación detallada! :-D – Dae

+0

Eventualmente abandoné REST a favor de la simple Ajax API. Aquí está mi código final para el procesamiento de mensajes de respuesta: http://pastie.org/2657317 – Dae

+0

Hombre esta es una gran explicación ... ¡Sencha necesita agregar esto a sus documentos! – HDave