所以,我已经写了一些代码,允许添加和从集合动态在ASP.NET MVC中使用AJAX移除元素。 添加新的项目,如预期的收集工作,但除去没有。 如预期(合适的项目被索引中删除)的模型集合更新,但呈现的HTML一再表明的最后一个项目已被删除(而不是一个指定索引处)。
举例来说,假设我有以下项目:
- 富
- 酒吧
- 巴兹
当我点击“删除”旁边名为“foo”的项目,我期望得到的呈现的HTML看起来如下:
- 酒吧
- 巴兹
当我通过控制器动作调试,这似乎是如此,因为模型上的名称集合只包含那些项目。 然而,回到我的AJAX的处理程序所提供的HTML是:
- 富
- 酒吧
我想这个问题可能与缓存的事,但没有我试过(OutputCache指令,设置高速缓存:$就假,等)工作。
下面是代码:
DemoViewModel.cs
namespace MvcPlayground.Models
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class DemoViewModel
{
public List<string> Names { get; set; }
public DemoViewModel()
{
Names = new List<string>();
}
}
}
DemoController.cs
这里的问题显然是在RemoveName方法。 我可以验证PartialViewResult的Model属性能够反映出集合状态,我期待它,但一旦呈现给客户端的HTML并不像我期待它。
namespace MvcPlayground.Controllers
{
using MvcPlayground.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
public class DemoController : Controller
{
// GET: Demo
public ActionResult Index()
{
var model = new DemoViewModel();
return View(model);
}
[HttpPost]
public ActionResult AddName(DemoViewModel model)
{
model.Names.Add(string.Empty);
ViewData.TemplateInfo.HtmlFieldPrefix = "Names";
return PartialView("EditorTemplates/Names", model.Names);
}
[HttpPost]
public ActionResult RemoveName(DemoViewModel model, int index)
{
model.Names.RemoveAt(index);
ViewData.TemplateInfo.HtmlFieldPrefix = "Names";
var result = PartialView("EditorTemplates/Names", model.Names);
return result;
}
}
}
Names.cshtml
这是我使用的呈现出名称列表进行编辑模板。 作品加入新的项目到集合时预期。
@model List<string>
@for (int i = 0; i < Model.Count; i++)
{
<p>
@Html.EditorFor(m => m[i]) @Html.ActionLink("remove", "RemoveName", null, new { data_target = "names", data_index = i, @class = "link link-item-remove" })
</p>
}
Index.cshtml
这是一个加载的初始页面,没有什么太复杂,在这里。
@model MvcPlayground.Models.DemoViewModel
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Demo</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="container-collection" id="names">
@Html.EditorFor(m => m.Names, "Names")
</div>
@Html.ActionLink("Add New", "AddName", "Demo", null, new { data_target = "names", @class = "btn btn-addnew" })
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
Index.js
该脚本处理,以AddName和RemoveName呼叫。 这里的一切工程,我所期待。
$('form').on('click', '.btn-addnew', function (e) {
e.preventDefault();
var form = $(this).closest('form');
var targetId = $(this).data('target');
var target = form.find('#' + targetId);
var href = $(this).attr('href');
$.ajax({
url: href,
cache: false,
type: 'POST',
data: form.serialize()
}).done(function (html) {
target.html(html);
});
});
$('form').on('click', '.link-item-remove', function (e) {
e.preventDefault();
var form = $(this).closest('form');
var targetId = $(this).data('target');
var target = form.find('#' + targetId);
var href = $(this).attr('href');
var formData = form.serialize() + '&index=' + $(this).data('index');
$.ajax({
url: href,
cache: false,
type: 'POST',
data: formData
}).done(function (html) {
target.html(html);
});
});