2011-09-25 23 views
17

ExtJs 4'ün RESTFul Store example üzerine yapıyorum. Komutumun, Ekle veya Sil isteği başarısız olduğunda REST sunucusu tarafından sağlanan hataları görüntülemesini istiyorum. Bir isteğin başarı durumunu almayı başardım (aşağıdaki kodu inceleyin), ancak yanıtla birlikte verilen iletiye nasıl ulaşabilirim?REST yanıt iletisi ExtJs 4'te nasıl edinilir?

Mağaza:

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

Tipik DİNLENME cevabı:

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

Belki tüm yanlış yapıyorum, bu yüzden herhangi bir tavsiye takdir edilmektedir.

cevap

25

Ben servis DİNLENME prensibini takip eder ve başarısız operasyonlar için 2xx dışındaki HTTP durum kodlarını kullanır varsayalım. Ancak, Ext 2xx durumuna dönmeyen yanıtlar için yanıt gövdesini değil yanıt gövdesi ayrıştırır. İstisna/yanıt nesnesi (yani 'istisna' olay dinleyicilerine geçirilir) gibi durumlarda sağlamaz response.statusText sadece HTTP durum mesajı nedir .

nedenle kendini JSON için responseText ayrıştırmak zorunda kalacaktır. Tek bir çizgi ile başarılabileceğinden, bu gerçekten sorun değil.

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

sizin kodlama stili bağlı olarak da 'beklenen' ve 'beklenmedik' HTTP hata durum kodları arasında bazı hata işleme ekleme ve/veya ayırt etmek isteyebilirsiniz. Bu davranışın nedeni, çünkü DİNLENME vekil sınıf veri paketindeki birinci sınıf üyesi olmama muhtemelen

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

(Bu Ext.data.reader.Json dan). HTTP durum kodlarını yalnızca haberleşme kanalı hataları için kullanan standart AJAX (veya JsonP) proxy davranışını da tanımlayan ortak bir taban sınıfından türetilmiştir. Bu nedenle, bu gibi durumlarda sunucudan ayrılabilir bir mesaj beklemezler. Uygulama hatalarını gösteren Sunucu yanıtları yerine Tamam HTTP durumu ve (success:"false" ve message:"[your error message]" ile) Söz ilan edilen bir JSON yanıtı ile iade edilmesi bekleniyor.

İlginç REST sunucusu olmayan bir 2xx durum ve bir yanıt gövdesinde (Ext açısından) geçerli bir JSON yanıt ile ve 'gerçek' olarak ayarlanır başarı özelliğiyle bir yanıt geri dönebilirler. Özel durum olayı yine de kovulur ve yanıt gövdesi ayrıştırılmamış olur. Bu kurulum pek bir anlam ifade etmiyor - sadece 'başarı' arasındaki farkın, vücuttaki başarı özelliğiyle karşılaştırıldığında (durumun ilkine göre önceliği olan), HTTP durum kodu açısından dikkat çekmek istiyorum.

Eğer uzatmak (veya geçersiz) olabilecek bir daha şeffaf çözüm için

Güncelleme Ext.data.proxy.Rest: Bu true için false gelen başarı değerini değiştirmek ve daha sonra standart processResponse uygulanmasını arayacak. Bu 'standart' Ext davranışını taklit eder ve responseText'i ayrıştırır. Elbette bu, orijinal yayınınızda success:"false" (veya başka bir şekilde başarısız) ile belirtildiği gibi standart bir JSON yanıtı bekleyecektir. Bu, test edilmemiş olsa da ve eğer ifade muhtemelen daha akıllı olmalıdır.

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

Süper!Mükemmel çalışır, detaylı açıklama için teşekkür ederim! : -D – Dae

+0

Sonunda basit Ajax API'sı lehine REST'i bıraktım. İşte yanıt mesajı işleme için son kodum: http://pastie.org/2657317 – Dae

+0

Bu harika bir açıklama ... Sencha bunu kendi dokümanlarına eklemeli! – HDave