Post ASP.NET MVC 页面部分加载 JQuery
Post an ASP.NET MVC page partially loaded with JQuery
所以我正在开发一个广告列表页面,我需要允许用户在不回发页面的情况下动态地向广告添加房间。我想用 Ajax 来减少所需的导航量,从而改善用户体验。
最初我查看了使用 Ajax 辅助方法来加载页面的动态元素。但是,由于 MVC/HTML 不支持嵌套表单,因此效果不佳。
Ajax.BeginForm inside Html.BeginForm
我最终使用了一些 JQuery 来加载房间和 Add/Remove 房间。 JQuery 在 adding/removing 个房间之后调用控制器上的一个动作来加载房间。
$("[name='RemoveRoom']").click(function () {
var url = $(this).data('url');
$('#roomsWrapper').load(url);
});
[HttpGet]
public ActionResult GetRooms(int Id)
{
var viewModel = this.roomAvailableAdvertStore.FindById(Id);
return PartialView("_Rooms", viewModel.Rooms);
}
我现在面临的问题是,当我提交表单时,这些动态加载的元素没有绑定到视图模型。解释得更清楚
<form>
@Html.HiddenFor(m => m.AdvertId);
<div id=”roomsWrapper”>
// These data items are not being bound to the model.
@Html.Partial(“_Rooms”, Model.Rooms);
</div>
<input type="submit" />
<form>
_Rooms.cshtml 部分页面如下所示:
@model List<RoomViewModel>
@for (int roomIndex = 0; roomIndex < Model.Count(); roomIndex++)
{
@Html.HiddenFor(m => m[roomIndex].RoomId)
}
表单回发到具有以下签名的操作:
public async Task<ActionResult> Update(RoomAvailableAdvertViewModel model)
{
...
}
视图模型如下所示:
public class RoomAvailableAdvertViewModel
{
public int AdvertId { get; set; }
public List<RoomViewModel> Rooms { get; set; }
}
感谢评论中留下的 link,我设法解决了这个问题。
基本上出现这个问题是因为默认的 ASP.net MVC 模型绑定器只能绑定到复杂类型的集合,前提是它们可以被唯一标识。 Phil Haack 在以下文章中更清楚地解释了这一切:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
但是,Phil 方法的局限性在于他对集合中的每个元素都应用了数字索引。当您尝试动态添加项目时,这种方法会失败,因为索引不是唯一的。
注释中给出的第二个 link 通过对集合中的每个元素应用一个 Guid 来解决这个问题,确保集合中的每个元素都有一个唯一的键。
http://blogs.interknowlogy.com/2014/08/01/mvc-series-part-1-dynamically-adding-
项目第 1 部分/
如果可以扩展 Razor 视图引擎以缓解此问题的发生,那将会很有趣。
所以我正在开发一个广告列表页面,我需要允许用户在不回发页面的情况下动态地向广告添加房间。我想用 Ajax 来减少所需的导航量,从而改善用户体验。
最初我查看了使用 Ajax 辅助方法来加载页面的动态元素。但是,由于 MVC/HTML 不支持嵌套表单,因此效果不佳。
Ajax.BeginForm inside Html.BeginForm
我最终使用了一些 JQuery 来加载房间和 Add/Remove 房间。 JQuery 在 adding/removing 个房间之后调用控制器上的一个动作来加载房间。
$("[name='RemoveRoom']").click(function () {
var url = $(this).data('url');
$('#roomsWrapper').load(url);
});
[HttpGet]
public ActionResult GetRooms(int Id)
{
var viewModel = this.roomAvailableAdvertStore.FindById(Id);
return PartialView("_Rooms", viewModel.Rooms);
}
我现在面临的问题是,当我提交表单时,这些动态加载的元素没有绑定到视图模型。解释得更清楚
<form>
@Html.HiddenFor(m => m.AdvertId);
<div id=”roomsWrapper”>
// These data items are not being bound to the model.
@Html.Partial(“_Rooms”, Model.Rooms);
</div>
<input type="submit" />
<form>
_Rooms.cshtml 部分页面如下所示:
@model List<RoomViewModel>
@for (int roomIndex = 0; roomIndex < Model.Count(); roomIndex++)
{
@Html.HiddenFor(m => m[roomIndex].RoomId)
}
表单回发到具有以下签名的操作:
public async Task<ActionResult> Update(RoomAvailableAdvertViewModel model)
{
...
}
视图模型如下所示:
public class RoomAvailableAdvertViewModel
{
public int AdvertId { get; set; }
public List<RoomViewModel> Rooms { get; set; }
}
感谢评论中留下的 link,我设法解决了这个问题。
基本上出现这个问题是因为默认的 ASP.net MVC 模型绑定器只能绑定到复杂类型的集合,前提是它们可以被唯一标识。 Phil Haack 在以下文章中更清楚地解释了这一切:
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
但是,Phil 方法的局限性在于他对集合中的每个元素都应用了数字索引。当您尝试动态添加项目时,这种方法会失败,因为索引不是唯一的。 注释中给出的第二个 link 通过对集合中的每个元素应用一个 Guid 来解决这个问题,确保集合中的每个元素都有一个唯一的键。
http://blogs.interknowlogy.com/2014/08/01/mvc-series-part-1-dynamically-adding- 项目第 1 部分/
如果可以扩展 Razor 视图引擎以缓解此问题的发生,那将会很有趣。