2011-09-25 63 views
17

我建立在ExtJs 4的RESTFul Store example上。我想讓我的腳本顯示由REST服務器提供的錯誤,當Add或Delete請求失敗時。我設法獲得了請求的成功狀態(請參閱下面的代碼),但是如何獲取響應中提供的消息?如何獲取ExtJs 4中的REST響應消息?

商店:

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

典型REST響應:

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

也許我做這一切錯誤的,所以任何建議表示讚賞。

回答

25

我假定您的服務遵循REST原則,並且使用除2xx以外的HTTP狀態代碼來執行不成功的操作。 但是,Ext將而不是解析響應正文的響應不返回狀態確定2xx。 什麼異常/響應對象(即傳遞給「異常」事件偵聽器)確實在這種情況下提供的僅僅是response.statusText中的HTTP狀態消息。

因此你必須自己解析responseText到JSON。這不是一個真正的問題,因爲它可以用一條線完成。

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

根據您的編碼風格您可能還需要添加一些錯誤處理和/或區分之間的「預期」和「意外」 HTTP錯誤狀態代碼。 (這是來自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; 
}, 

這樣做的原因行爲是因爲不是在數據包的第一類件的REST代理類的可能。它來源於一個通用的基類,它也定義了標準AJAX(或JsonP)代理的行爲,該代理僅使用HTTP狀態代碼來處理通信通道錯誤。因此,在這種情況下,他們不會期望來自服務器的任何可解析消息。 指示應用程序錯誤的服務器響應預計將返回HTTP狀態OK和發佈在您的問題中的JSON響應(success:"false"message:"[your error message]")。

有趣的是,一個REST服務器可以返回一個非2xx狀態的響應和一個有效的JSON響應的響應體(以Ext的形式)並且success屬性設置爲'true'。異常事件仍然會被觸發並且響應正文未被解析。 這種設置並沒有什麼意義 - 我只是想指出HTTP狀態代碼與成功屬性相比,「成功」的區別(第一個優先於後者)。

更新

對於一個更加透明的解決方案可以擴展(或重寫)Ext.data.proxy.Rest:這會從false成功的值更改爲true,然後調用標準processResponse實施。這將模擬'標準'Ext行爲並解析responseText。當然,這將期望標準JSON響應,如原始帖子中概述的success:"false"(或其他失敗)。 儘管如此,if表達式可能應該更聰明。

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

超級!完美的作品,謝謝你的詳細解釋! :-D – Dae

+0

最終我放棄了REST,轉而使用簡單的Ajax API。這是我的最終響應消息處理代碼:http://pastie.org/2657317 – Dae

+0

這是一個很好的解釋... Sencha需要將它添加到他們的文檔! – HDave

相關問題