【问题标题】:How to replace div's content by partial view or update it's content depending on what json result returns on ajax complete?如何通过部分视图替换div的内容或根据ajax完成时返回的json结果更新它的内容?
【发布时间】:2013-08-08 19:01:30
【问题描述】:

我有简单的 ajax 形式:

这是MyPartialView

@using(Ajax.BeginForm("action", "controller", new AjaxOptions
{
    OnBegin = "beginRequest",
    OnComplete = "completeRequest",
    HttpMethod = "POST",
    InsertionMode = InsertionMode.Replace,
    UpdateTargetId = "div-to-replace"
}, }))
{
    <input type="text" id="my-input" /> 
    ...
}

这是父视图:

<div id="div-to-replace">
    @Html.RenderPartial("MyPartialView")
</div>

在我的控制器中,我有:

[HttpPost]
public ActionResult action(Model model)
{
   if (ModelState.IsValid)
   {
      // do staff with model
      // return partial view
      return PartialView("MyPartialView");
   }
   // else add error and return json result
   return Json(new {error = "invalid data"});
}

还有我在 ajax 上完成的 javascript 方法:

function completeRequest(data) {
    var result = $.parseJSON(data.responseText);

    if (result != 'undefined' && result != null && result.error) {
        // just display error and not replace  all content
        // attachModelError is my custom method, it just adds vlaidation-error class to inputs, etc.
        attachModelError("my-input", result.error);
        return;
    }

    // or show returned html (depending on returned model form inputs will be modified:
    // select box with different items in my case
    $('#div-to-replace').html(data.responseText);
}

但问题是,如果模型状态无效,我的 #div-to-replace 为空。如果模型状态正常,则一切正常。如果我使用不同的插入模式,它会在 div 之前或之后创建 div 内容的副本。

总结:
我想要不同的InsertionMode 行为,具体取决于json 结果。我不需要替换数据if (result != 'undefined' &amp;&amp; result != null &amp;&amp; result.error)。

【问题讨论】:

  • 但在 if 语句代码块中没有设置 #div-to-replace 的 html
  • 当模型状态无效时您想要的确切行为是什么?在 div-to-replace 中显示错误消息?
  • @Johan,我已经更新了问题。
  • @TheGeekYouNeed,查看我的摘要编辑。

标签: c# asp.net-mvc json jquery


【解决方案1】:

很久以前我不得不解决一次这个问题。我想出了一个简单的解决方案,今天它可能不是最好的解决方案,但它可以完成工作。

我的解决方案涉及设置一个控制器操作,该操作将仅使用它需要的数据呈现部分,并让我的 JavaScript 请求它。

C#

MyController: Controller 
{
  public ActionResult GetPartialViewAction()
  {
    return PartialView("mypartialview", new partialViewModel());
  }
}

JavaScript

$.ajax({
  url: "/my/getpartialaction/"
}).done(function(data) {
  $("#partialViewDiv").html(data);
});

HTML

<div id="partialViewDiv"></div>

更好的解决方案是使用 MVVM/MVC JavaScript 库,该库允许您利用 html 模板,并且只需通过 ajax 解决方案传输数据。我建议查看 knockout.js 或 backbone.js 以了解这种更被接受的模式。

【讨论】:

  • 其实我的action 只返回MyPartialView 里面的#div-to-replace。你可能没看懂我的问题。我想要不同的InsertionMode 行为,具体取决于json 结果。我不需要替换数据if (result != 'undefined' &amp;&amp; result != null &amp;&amp; result.error)。
  • 您的解决方案应该可以正常工作,因为您已对其进行了更改。实际上没有发生什么?
  • 这个解决方案很棒,但它缺少作为 function() 参数的数据,导致它失败。
【解决方案2】:

我对默认的 c# ajax 表单也有同样的问题。我有一个可行的解决方案。

jQuery:

$(function () {

var ajaxFormSubmit = function () {

    var $form = $(this);

    var options = {
        url: $form.attr("action"),
        type: $form.attr("method"),
        data: $form.serialize(),
        cache: false
    }

    $.ajax(options).done(function (data) {

        data.replaces.each(function (replace) {

            $(replace.id).replaceWith(replace.html);

        });

    });

    return false;
};

$("form[data-ajax='true']").submit(ajaxFormSubmit);});

form.cshtml

@using (Html.BeginForm("Create", "Menu", FormMethod.Post, new { data_ajax = "true" }))
{}

模型样本

public string Id {get;set;}
public string Html {get;set;}

您需要在控制器中做的最后一件事是返回一个带有模型示例列表的 json 结果,id 是要更新的目标元素,对于 html,您必须使用渲染部分 / 或视图作为字符串。

对于部分渲染视图,请参阅 [问题]:https://stackoverflow.com/questions/434453

【讨论】:

  • 您好,我试过这段代码,效果很好,但是如何结合文件上传使用呢?我将 i 更改为:new { enctype = "multipart/form-data", data_ajax="true"})),但随后我的文件为空,当我删除 data_ajax 时,我的文件已上传..Thanx 提前
  • 您可能需要添加一些额外的选项,例如:enctype: 'multipart/form-data', processData: false, contentType: false, cache: false
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多