我在MVC中有一个局部视图,如下所示:
<div id="comments">
...
</div>
在div内部有一个使用AJAX调用控制器的表单并返回相同的局部视图。问题是调用视图的结果替换了div的内容,而不是整个div,我最终得到:
<div id="comments">
<div id="comments">
...
</div>
</div>
我在ASP.Net MVC和AJAX中的一周经验可以考虑的唯一解决方案是将div放在局部视图之外并使局部视图仅包含内部部分,但是表单将引用外部的id查看表单所在的位置,打破了我留在那里的小封装。有没有更好的解决方案?
.NET MVC 3附带的不显眼的Ajax库使用基于jQuery.ajax的四个回调的回调。但是,Ajax.BeginForm方法中的InsertionMode = InsertionMode.Replace可以 不 导致jQuery的replaceWith被调用。相反,.html(数据)用于替换 内容 目标元素(而不是元素本身)。
我在博客上描述了这个问题的解决方案:
http://buildingwebapps.blogspot.com/2011/11/jquerys-replacewith-and-using-it-to.html
.NET MVC 3附带的不显眼的Ajax库使用基于jQuery.ajax的四个回调的回调。但是,Ajax.BeginForm方法中的InsertionMode = InsertionMode.Replace可以 不 导致jQuery的replaceWith被调用。相反,.html(数据)用于替换 内容 目标元素(而不是元素本身)。
我在博客上描述了这个问题的解决方案:
http://buildingwebapps.blogspot.com/2011/11/jquerys-replacewith-and-using-it-to.html
您使用的是AjaxHelper.Form还是jQuery。如果您使用的是jQuery,请尝试使用 用。。。来代替()?您正在使用AjaxHelper AjaxOptions { InsertionMode = InsertionMode.Replace }
?我认为使用任何一种都可以用部分视图的结果替换整个DIV。
运用
AjaxOptions { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace }
应该取代'#myDiv'元素的全部内容,正如tvanfosson所说。你的问题是'#myDiv'所在的位置。这是一个例子:
<div id="myDiv">
<% Html.RenderPartial("MyPartialView"); %>
</div>
MyPartialView的位置是:
<div id="comments">
<% using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace } )) {%>
...
<input type="submit" value="Submit comment" />
<% } %>
</div>
如果在局部视图中包含'#myDiv'div,它将在收到响应(及其内容)后立即呈现,然后它的内容将替换为相同局部视图的响应(包括它自己的' #myDiv'div),这就是为什么你总是最终得到2个嵌套的div。
您应始终为部分视图使用容器,然后将UpdateTargetId设置为容器ID。
编辑: 我更新了代码,以表示您在问题中描述的确切情况。
我在Asp.Net MVC 5中遇到了同样的问题。
我不希望PartialView知道它可能包含哪些div,所以我不接受这种解决方法。
然后,我注意到其他答案引用了ReplaceWith并找到了简单的解决方案:
InsertionMode = InsertionMode.ReplaceWith
现在,mvc局部视图可以完全用ajax助手替换自己,而不会对名称之外的任何依赖。
你应该尝试使用jQuery(从我的答案开始) MS MVC形成AJAXifying技术):
<script type="text/javascript">
$(document).ready(function() {
ajaxify($('div#comments'));
});
function ajaxify(divWithForm) {
var form = $('form', divWithForm);
$(':submit', form).click(function (event) {
event.preventDefault();
$.post(form.attr('action'), form.serialize(),
function(data, status) {
if(status == 'success') {
var newDivWithForm = $(data);
ajaxify(newDivWithForm);
divWithForm.after(newDivWithForm).remove();
}
}
);
});
}
</script>