简体   繁体   English

ASP.NET MVC使用jQuery ajax渲染局部视图

[英]ASP.NET MVC rendering partial view with jQuery ajax

I have a controller action which renders a partial view: 我有一个控制器动作,呈现局部视图:

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

and I'm loading the returned content into a dynamic element as follows: 我将返回的内容加载到动态元素中,如下所示:

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

so this creates a div, and then loads the returned content into that div. 所以这会创建一个div,然后将返回的内容加载到该div中。

I want to alter this slightly so that the container div is only created if the call to the controller is succesful. 我想略微改变它,以便只有在对控制器的调用成功时才创建容器div。

So: 所以:

  1. jQuery calls the controller action jQuery调用控制器动作
  2. controller returns PartialView, or null if Id not found controller返回PartialView,如果未找到Id,则返回null
  3. If PartialView is returned, the container is created and loaded with the returned content. 如果返回PartialView,则会创建容器并使用返回的内容加载容器。
  4. If the controller doesn't find the Id, no content is created and an alert is displayed. 如果控制器未找到Id,则不会创建任何内容并显示警报。

I'd appreciate any pointers on how I could best acheive this. 我很感激有关如何最好地实现这一点的任何指示。

in your case i would use $.ajax instead of .load() gives you more control over the flow + feels more clean 在你的情况下,我会使用$ .ajax而不是.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
   }
});

concerning the error state - i also hate relying on exceptions - ugly and inefficient, you have several ways to handle this: 关于错误状态 - 我也讨厌依赖异常 - 丑陋和低效,你有几种方法可以解决这个问题:

  1. return only JSON from your views and bind the returned data using some sort of templating solution, this way you can return an error object with a specific error message and handle all errors the same way(think this is the best solution). 从您的视图中仅返回JSON并使用某种模板解决方案绑定返回的数据,这样您就可以返回带有特定错误消息的错误对象并以相同的方式处理所有错误(认为这是最佳解决方案)。
  2. return a 204 success status code -no response which is like returning null from your action - then check the status code and pop up the error message. 返回204成功状态代码 - 无响应,就像从您的操作中返回null - 然后检查状态代码并弹出错误消息。
  3. return a 278 success status code(not a real status code but is counts for success and lets you also send data) - here you send a json object with the error message which tou can parse and sow a nice error message (saw this 278 solution here in SO sometime ago). 返回一个278成功状态代码(不是一个真实的状态代码,但是成功的数量,并让你也发送数据) - 在这里你发送一个json对象与错误消息,tou可以解析并播下一个很好的错误消息(看到这278解决方案在某些时候在这里)。
  4. return a different view for the error - but then you have to insert it to the container or a dummy container to check if there is an error if you want to take more actions. 返回错误的不同视图 - 但是如果要采取更多操作,则必须将其插入容器或虚拟容器以检查是否存在错误。

in my code i use $(document).ajaxSend(..) to globally check all Ajax responses for 278 code and show the error messages if there is any, or call the original hooked success function. 在我的代码中,我使用$(document).ajaxSend(..)来全局检查278代码的所有Ajax响应并显示错误消息(如果有),或者调用原始的hooked success函数。

To return the error from the action i use the following result 要从操作中返回错误,请使用以下结果

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

where ErrorResult can be an anonymous object or an object that implement an interface with a property of ErrorMessage so you will know what to look for at the JS 其中ErrorResult可以是一个匿名对象,也可以是一个实现具有ErrorMessage属性的接口的对象,因此您将知道在JS中寻找什么

All load does is return HTML from a server, so why not just append to a temporary div and then get the HTML from it on success? 所有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: 更新:

If you're expecting an exception then you should handle it. 如果您期待异常,那么您应该处理它。 If you're basically allowing the error to occur just to get status != "success" then that's a serious code smell. 如果你基本上允许错误发生只是为了获得status != "success"那么这是一个严重的代码味道。 You should catch the error and return a different PartialView. 您应该捕获错误并返回不同的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);
    }
}

Then you're guaranteed to always get a valid HTML response and if you don't, then your basic error an error occured will come into play. 然后你肯定会得到一个有效的HTML响应,如果你没有,那么你的基本错误就会an error occured

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM