我不想使用ViewBag值,所以我使用隐藏元素的属性来跟踪用户的排序选择。
我有一个主页索引页面,其中包含一个内部局部视图,该视图显示用户活动日志表中的一个部分。表格有一个标题行,在大多数列中都有一个下拉列表和右对齐的排序图标。当用户点击排序图标时,数据按该列升序或降序排序(取决于排序切换状态)。
提前道歉,我为这个简单的解决方案补充了很多代码,但我认为为了给看我的答案的人(可能是新手)提供完整的上下文,代码补充应该有助于组合一个简单而完整的数据检索和排序切换解决方案,而不使用ViewBags。
代码用法解释在帖子底部。
我的Index视图(隐藏元素所在的位置)。这里的sort
属性是主要关注点:
<div class="hidden">
<span id="act-user-sort" sort=""></span>
<span id="act-type-sort" sort=""></span>
<span id="act-level-sort" sort=""></span>
<span id="act-date-sort" sort=""></span>
</div>
<section id="partial_Activity">
@Html.Action("_Activity", "Home")
</section>
ActionResult "_Activity"最初返回上述Index视图中的"_Activity"部分视图:
public ActionResult _Activity()
{
using (var context = new ApplicationDbContext())
{
LogModel logModel = new LogModel();
LogSelect logSelect = new LogSelect();
var result = from log in context.Logs
join user in context.Users on log.UserId equals user.Id into userlog
from user in userlog.DefaultIfEmpty()
orderby log.LogDate descending
select new Models.UserActivity { Log = log, User = user };
logSelect.LogUsers = result.Select(u => new LogUser { Name = u.User.FirstName + " " + u.User.LastName, Id = u.User.Id }).Distinct().ToList();
logSelect.LogTypes = result.Select(t => t.Log.Type).Distinct().ToList();
logSelect.LogLevels = result.Select(t => t.Log.Level).Distinct().ToList();
int pageIndex = 1;
int pageSize = 10;
PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize);
logModel.LogSelect = logSelect;
logModel.UserActivity = pgList;
return PartialView(logModel);
}
}
我的 "_Activity" 操作部分视图(包含表格和排序按钮):
@model Utils.Models.LogModel
<style>
...
</style>
<div>
<h3>Recent Activity</h3>
</div>
<div style="height:20px"></div>
@* the panel class rounds the corners of the table *@
<div class="panel panel-default table-responsive" style="font-size:.9em;">
<table id="log-table" class="table table-striped table-bordered table-hover log-table" style="width:100%;">
<thead>
<tr class="bg-primary">
<th class="dropdown log-dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle">User <b class="caret"></b></a>
<div class="log-dropdown-sort log-dropdown-sort-init">
<a sort="" href="#" id="log-dropdown-user-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a>
</div>
<ul id="log-dropdown-user" class="dropdown-menu log-dropdown">
@foreach (var user in Model.LogSelect.LogUsers)
{
<li><a id="log-user" href="#">@user.Name</a><span id="log-user-id" class="hidden">@user.Id</span></li>
}
</ul>
</th>
<th>Action</th>
<th class="dropdown log-dropdown">
<a href="#" data-toggle="dropdown" class="dropdown-toggle">Type <b class="caret"></b></a>
<div class="log-dropdown-sort log-dropdown-sort-init">
<a sort="" href="#" id="log-dropdown-type-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a>
</div>
<ul id="log-dropdown-type" class="dropdown-menu">
@foreach (var log in Model.LogSelect.LogTypes)
{
<li><a id="log-type" href="#">@log</a><span class="hidden">@log</span></li>
}
</ul>
</th>
<th class="log-dropdown">
Date
<div class="log-dropdown-sort log-dropdown-sort-init">
<a sort="" href="#" id="log-dropdown-date-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a>
</div>
<div class="log-dropdown-date log-dropdown-date-init">
<a href="#" id="log-dropdown-date-range"><img src="~/Images/ui/calendar-white.png" /></a>
</div>
</th>
</tr>
</thead>
<tbody>
@foreach (var log in Model.UserActivity)
{
<tr>
<td>@log.User.FirstName @log.User.LastName</td>
<td class="log-message">@log.Log.Message</td>
<td>@log.Log.Type</td>
<td class="log-date">@log.Log.LogDate</td>
</tr>
}
</tbody>
</table>
</div>
<div>
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
@for (int pg = 1; pg <= Model.UserActivity.TotalPages; pg++)
{
if (pg == Model.UserActivity.PageIndex)
{
<li class="active"><a href="#">@pg</a></li>
}
else
{
<li><a href="#">@pg</a></li>
}
}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</div>
处理事件的jQuery代码如下:
$('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {
e.preventDefault();
var data = {};
data.sortOrder = setSort($("#act-user-sort"), "user");
GetActivity(data);
});
$('#partial_Activity').on('click', '#log-dropdown-type-sort', function (e) {
e.preventDefault();
var data = {};
data.sortOrder = setSort($("#act-type-sort"), "type");
GetActivity(data);
});
$('#partial_Activity').on('click', '#log-dropdown-level-sort', function (e) {
e.preventDefault();
var data = {};
data.sortOrder = setSort($("#act-level-sort"), "level");
GetActivity(data);
});
$('#partial_Activity').on('click', '#log-dropdown-date-sort', function (e) {
e.preventDefault();
var data = {};
data.sortOrder = setSort($("#act-date-sort"), "date");
GetActivity(data);
});
function setSort(element, sort) {
if (element.attr("sort") == "") {
element.attr("sort", "asc");
sort = sort + "_asc";
}
else {
if (element.attr("sort") == "asc") {
element.attr("sort", "desc")
sort = sort + "_desc";
}
else {
element.attr("sort", "asc")
sort = sort + "_asc";
}
}
return sort;
}
function GetActivity(options) {
$.ajax({
cache: false,
type: "GET",
url: "../Home/GetActivity",
data: options,
contentType: "application/json; charset=utf-8",
success: function (obj) {
$("#partial_Activity").html(obj);
}
}).done(function () {
});
}
当用户点击排序按钮时,会返回部分视图的GET方法:
[HttpGet]
public PartialViewResult GetActivity(
string sortOrder,
string userFilter,
string typeFilter,
string levelFilter,
DateTime? startDate,
DateTime? endDate,
int pageIndex = 1,
int pageSize = 10)
{
using (var context = new ApplicationDbContext())
{
LogModel logModel = new LogModel();
LogSelect logSelect = new LogSelect();
var result = from log in context.Logs
join user in context.Users on log.UserId equals user.Id into userlog
from user in userlog.DefaultIfEmpty()
orderby log.LogDate descending
select new Models.UserActivity { Log = log, User = user };
logSelect.LogUsers = result.Select(u => new LogUser { Name = u.User.FirstName + " " + u.User.LastName, Id = u.User.Id }).Distinct().ToList();
logSelect.LogTypes = result.Select(t => t.Log.Type).Distinct().ToList();
logSelect.LogLevels = result.Select(t => t.Log.Level).Distinct().ToList();
if (!String.IsNullOrEmpty(userFilter)) { result = result.Where(r => r.User.UserName.Equals(userFilter)); }
if (!String.IsNullOrEmpty(typeFilter)) { result = result.Where(r => r.Log.Type.Equals(typeFilter)); }
if (!String.IsNullOrEmpty(levelFilter)) { result = result.Where(r => r.Log.Level.Equals(levelFilter)); }
if (startDate.HasValue) { result = result.Where(r => r.Log.LogDate >= startDate); }
if (endDate.HasValue) { result = result.Where(r => r.Log.LogDate <= endDate); }
result = result.OrderByDescending(r => r.Log.LogDate);
switch (sortOrder)
{
case "date_asc":
result = result.OrderBy(r => r.Log.LogDate);
break;
case "date_desc":
result = result.OrderByDescending(r => r.Log.LogDate);
break;
case "user_asc":
result = result.OrderBy(r => r.User.FirstName)
.ThenByDescending(r => r.Log.LogDate);
break;
case "user_desc":
result = result.OrderByDescending(r => r.User.FirstName)
.ThenByDescending(r => r.Log.LogDate);
break;
case "type_asc":
result = result.OrderBy(r => r.Log.Type)
.ThenByDescending(r => r.Log.LogDate);
break;
case "type_desc":
result = result.OrderByDescending(r => r.Log.Type)
.ThenByDescending(r => r.Log.LogDate);
break;
case "level_asc":
result = result.OrderBy(r => r.Log.Level)
.ThenByDescending(r => r.Log.LogDate);
break;
case "level_desc":
result = result.OrderByDescending(r => r.Log.Level)
.ThenByDescending(r => r.Log.LogDate);
break;
default:
break;
}
PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize);
logModel.LogSelect = logSelect;
logModel.UserActivity = pgList;
return PartialView("_Activity", logModel);
}
}
解释:
当您在
_Activity
局部视图中单击
<a id="log-dropdown-user-sort"><img.../></a>
时,JavaScript点击事件
$('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {}
将触发并调用
setSort(DOM element, string)
函数。
setSort()
函数设置传递元素的
"sort"
属性,将属性值在
'asc'
和
'desc'
之间切换,从而影响函数内未来的逻辑流,并返回一个连接的字符串值,该值将用作下一步调用的
GetActivity
GET方法中的
sortOrder
参数。
然后,
GetActivity
GET方法根据
switch
语句评估的
sortOrder
参数查询并返回排序数据。