2010-09-06 88 views
5

我有這使得一個局部視圖控制器動作:ASP.NET MVC渲染與jQuery AJAX局部視圖

public ActionResult Details(int id) 
{ 
    DetailsViewModel model = 
     ModelBuilder.GetDetailsViewModel(id, _repository); 
    return PartialView("Details", model); 
} 

和我加載返回的內容爲動態元素如下:

$container = appendContainer(); // adds a div to the dom with the correct id 
$container.load("MyController/Details", function(response, status, xhr) { 
    if (status != "success") { 
     $(container).html('an error has occured'); 
    } 
}); 

所以這創建一個div,然後將返回的內容加載到該div。

我想稍微改變一下,這樣只有在控制器的調用 成功時才創建容器div。

所以:

  1. jQuery的調用控制器動作,如果ID未發現
  2. 如果返回PartialView,創建容器,並加載了返回的內容
  3. 控制器返回PartialView,或者爲null。
  4. 如果控制器未找到標識,則不會創建任何內容並顯示警報。

我很感激任何關於如何最好地實現這一目標的指針。

回答

11

全部load確實是從服務器返回HTML,爲什麼不直接追加到臨時div,然後從成功獲取HTML?

var $dummy = $("<div>"); 
$dummy.load("MyController/Details", function(response, status, xhr) { 
    var $container = appendContainer(); 
    if (status != "success") { 
     $container.html('an error has occured'); 
    } 
    else 
    { 
     $container.html($dummy.html()); 
    } 
    $dummy.remove(); 
}); 

UPDATE:

如果你期待一個例外,那麼你應該處理它。如果你基本上允許錯誤發生只是爲了得到status != "success"那麼這是一個嚴重的代碼異味。您應該捕獲錯誤並返回一個不同的PartialView。

public ActionResult Details(int id) 
{ 
    try 
    { 
     DetailsViewModel model = 
      ModelBuilder.GetDetailsViewModel(id, _repository); 
     return PartialView("Details", model); 
    } 
    catch (SomeException ex) 
    { 
     return PartialView("Error", ex.Message); 
    } 
} 

然後你保證總能獲得一個有效的HTML響應,如果你不這樣做,那麼你的基本誤差an error occured將開始發揮作用。

+0

我對此的保留意見是,我基本上在View中使用未捕獲的異常,以便向UI返回空/未找到的狀態。如果找不到該項目,我寧願從我的控制器返回一個空值,但我看不到一種方法來處理這個問題。只是似乎有點代碼味道給我。 – fearofawhackplanet 2010-09-06 15:46:42

+0

@fearofawhackplanet - 更新了我的答案。 – GenericTypeTea 2010-09-06 16:02:48

11

你的情況我會用$就代替.load() 讓你更好地控制流量+感覺更乾淨

$.ajax({ 
url: "MyController/Details", 
    type: "GET", 
    success: function (response, status, xhr) 
    { 
     var jqContainer = appendContainer(); 
     jqContainer.html(response); 
    }, 
    error:function(XMLHttpRequest, textStatus, errorThrown) 
    { 
    //show the error somewhere - but this is a bad solution 
    } 
}); 

有關錯誤狀態 - 我也很討厭依託例外 - 醜陋和低效, 你有幾種方式來處理這個問題:

  1. 從您的觀點僅返回JSON並綁定使用某種模板解決方案返回的數據,這樣你可以用一個特定的錯誤信息返回一個錯誤對象並處理所有的錯誤或以同樣的方式(認爲這是最好的解決方案)。
  2. 返回一個204成功狀態碼 - 無響應,就好像你的動作返回null - 然後檢查狀態碼並彈出錯誤信息。
  3. 返回278成功狀態碼(不是一個真實的狀態碼,但是可以計數成功並且可以發送數據) - 在這裏你發送一個帶有錯誤信息的json對象,該信息可以解析和播種一個很好的錯誤信息這個278解決方案在某個時間以前在這裏)。
  4. 返回錯誤的不同視圖 - 但是,如果您想採取更多操作,則必須將其插入容器或虛擬容器以檢查是否存在錯誤。
在我的代碼

我使用的$(document).ajaxSend(..)在全球範圍內檢查278代碼的所有Ajax響應並顯示錯誤消息,如果有任何,或調用原始掛鉤成功的功能。

要我用下面的結果動作返回錯誤

public class AjaxErrorWithDetailsResult : JsonResult 
    { 
    public object ErrorResult { get; set; } 

    public AjaxErrorWithDetailsResult(object errorResult) 
    { 
     this.ErrorResult = errorResult; 
    } 


    public override void ExecuteResult(ControllerContext context) 
    { 
     if (context == null) 
     { 
      throw new ArgumentNullException("context"); 
     } 
     this.Data = ErrorResult; 
     context.HttpContext.Response.StatusCode = 278; 
     base.ExecuteResult(context); 
    } 
} 

其中ErrorResult可以實現用的ErrorMessage的屬性的接口的匿名對象或對象,所以你就知道要尋找什麼在JS

+1

我同意你的意見! $ ajax可以更好地控制流量。 – 2016-11-10 13:11:34