【发布时间】:2016-12-05 11:21:22
【问题描述】:
自学 MVC,所以我想完成的第一个项目是一个使用 Bootstraps 模态表单的简单 CRUD 应用程序。
我试图让我对这个学习项目的要求尽可能真实……因此
- 分页搜索(最好是自动完成,因为不需要提交按钮)
- 维护当前的搜索参数
- 带有模态形式的 CRUD
- 可能通过 AJAX 加载?
我基本上已将以下 2 个项目融合到一个工作应用程序中。
- Sorting, Filtering, and Paging with the Entity Framework in an ASP.NET MVC Application
- Crud operation in ASP.NET MVC using Ajax
我的应用程序有一些问题...首先,在我的 HttpPostActionResult 中,如果我返回 PartialView("_DetailPaged"),_DetailPage 部分告诉我模型为空。因为 _detailPage 正在寻找 PagedList.IPagedList 的模型,所以理论上我必须重新运行 Index 操作中的代码。
所以,我改为尝试返回 RedirectToAction("Index"),只要模型能够正确加载,它就可以正常工作,但是,因为我正在重新加载我的视图,所以 UI 的某些部分会重复。
理想情况下,我希望能够通过 ajax 加载搜索并且只更新详细信息部分。
我希望允许用户在不使用提交按钮的情况下搜索表格,因此有上述要求,最后,我希望能够返回带有搜索参数的查询,即使在编辑或添加之后也是如此。
作为奖励,我想清理搜索查询以仅返回数据的子集,即这 10 条记录,并带有关于如何查询下一个或前 10 个的书签。
任何建议将不胜感激。
我的观点
<div id="main-div">
<div class="clearfix"> </div>
<div class="clearfix"> </div>
<div class="container">
<a href="@Url.Action("Add", "MVCPager2")" id="Add" class="btn btn-primary"><i class="glyphicon glyphicon-plus"></i> Create New</a>
<div id="div-record">
@Html.Partial("_DetailPaged", Model)
</div>
</div>
<div class="modal fade" id="Add-Model" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">New Student</h4>
</div>
<div class="divForAdd">
</div>
</div>
</div>
</div>
<div class="modal fade" id="Edit-Model" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Update Student</h4>
</div>
<div class="divForUpdate">
</div>
</div>
</div>
</div>
局部视图
@model PagedList.IPagedList<Employee>
@using PagedList.Mvc;
@using (Html.BeginForm("Index", "MVCPager", FormMethod.Get))
{
<p>
Find by name: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string)
<input type="submit" value="Search" />
</p>
}
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
<a href="@Url.Action("Edit", "Home", new { ID = item.EmployeeID })" class="editDialog"><i class="fa fa-pencil-square-o"></i> Edit</a>
</td>
<td>
@Ajax.ActionLink("Delete", "Delete", "Home", new { @ID = item.EmployeeID }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "div-record" }, new { @class = "fa fa-trash-o" })
</td>
</tr>
}
</tbody>
</table>
<br />
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
</div>
<script>
$(document).ready(function () {
$('#Add').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForAdd').html(response);
});
$('#Add-Model').modal({
backdrop: 'static',
}, 'show');
});
$('.editDialog').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForUpdate').html(response);
});
$('#Edit-Model').modal({
backdrop: 'static',
}, 'show');
});
});
</script>
我的控制器
public ActionResult Index(string sortOrder, string currentFilter, string searchString, int? page)
{
ViewBag.CurrentSort = sortOrder;
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
IEnumerable<Employee> Employees;
using (NorthwindEntities ctx = new NorthwindEntities())
{
Employees = ctx.Employees.ToList();
}
if (!String.IsNullOrEmpty(searchString))
{
Employees = Employees.Where(s => s.LastName.Contains(searchString)
|| s.FirstName.Contains(searchString));
}
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(Employees.ToPagedList(pageNumber, pageSize));
}
public ActionResult Add()
{
return PartialView("_AddPaged");
}
[HttpPost]
public ActionResult Add(Employee model)
{
List<Employee> Employees = new List<Employee>();
if (ModelState.IsValid)
{
using (NorthwindEntities ctx = new NorthwindEntities())
{
Employee _employee = new Employee
{
FirstName = model.FirstName,
LastName = model.LastName
};
ctx.Employees.Add(_employee);
try
{
ctx.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
Employees = ctx.Employees.ToList();
}
}
return RedirectToAction("Index");
//return PartialView("_DetailPaged");
}
【问题讨论】:
标签: ajax asp.net-mvc-4 twitter-bootstrap-3 bootstrap-modal