2014-02-24 21 views
1

我有一個ASP MVC應用程序,它允許用戶通過jQuery ajax調用將多個部分視圖添加到div。本地成功事件之前的全局ajaxSuccess事件

jQuery("#AddNew").click(function() { 
    $.ajax({ 
     url: this.href, 
     cache: false, 
     success: function (html) { 
      jQuery("#DivId").append(html); 
     } 
    }); 
    return false; 
}); 

的問題是,由於用戶必須被授權的行動返回局部視圖,當用戶的會話超時,則呈現登錄頁面,而不是局部視圖。我有使用類似AJAX調用多個地方,所以我增加了以下作爲一個全球性的ajaxSuccess事件:

jQuery(document).ajaxSuccess(function (event, request, settings) { 
    var isLogin = jQuery(request.responseText).find('.login-form').length; 
    if (isLogin > 0) { 
     var url = document.URL; 
     var rootPath = '@Request.Url.GetLeftPart(UriPartial.Authority)'; 
     var path = url.replace(rootPath, ''); 
     var pathEncoded = encodeURIComponent(path); 
     var loginURL = rootPath + "/Account/Login?returnUrl=" + pathEncoded; 
     location.href = loginURL; 
    } 
}); 

這工作,因爲這將用戶重定向到登錄頁面時,未經授權的AJAX請求。但是,它仍然將html添加到div,在重定向之前很短的時間內可見。

有沒有辦法讓全局事件在本地觸發之前觸發? jQuery API顯示本地成功事件在全局ajaxSuccess事件之前觸發,所以我嘗試更改ajax調用以使用完整而非成功。這確實奏效,但似乎是因爲某些原因,我需要在未來添加代碼才能成功執行,我會遇到同樣的問題。有沒有更好的方法來處理這個問題?

回答

1

我可能會建議創建您自己的API包裝ajax方法,確保您所需的功能(特別是操作的順序)。這裏是一個非常過於簡單例子:

var async = function(props) { 
    var finished = $.Deferred(); 
    $.ajax(props) 
    .done(function(response) { 
     // detect auth timeout, handle consisently 
     if(response.isAuthTimeout) { 
     // render login ui 
     finished.reject('auth-timeout'); 
     } else { 
     finished.resolve.apply(finished, arguments); 
     } 
    }) 
    .fail(function() { 
     finished.reject.apply(finished, arguments); 
    }) 
    return finished; 
}; 

然後,在實踐中,你會打電話給async(或任何你決定打電話給你的包裝),而不是本地$.ajax API。

有意義嗎?

+0

另外,這裏額外的好處是這種認證超時實際上會導致拒絕相關的承諾。即使實際的HTTP請求成功,您也會說,等待 - 根據我們的API,這實際上是一個失敗! – Skone

+0

是的,這是有道理的,這似乎是一個更好的處理方法。在這個應用程序中,這不是一個大問題,我認爲(現在至少)我們只接受在重定向之前顯示的視圖,而不是改用本地ajax函數以外的東西。 – michael