Я не хотел использовать значение ViewBag, так что я вместо этого использовал атрибуты скрытых элементов, чтобы сохранить отслеживать выбор сортировки пользователя.
У меня есть страница Home Index с внутренним частичным представлением, что в разделе, отображающем таблицу журналов действий пользователя. В таблице есть строка заголовка, и в большинстве столбцов есть раскрывающийся список и правый-значный значок сортировки. Когда пользователь щелкает значок сортировки, данные сортируются по этому столбцу в порядке возрастания или убывания (в зависимости от статуса переключения сортировки).
Заранее извиняюсь за то, что я добавил столько кода для этого простого решения, но я думаю, что для полного контекста для человека (возможно, новичка), который смотрит на мой ответ, дополнения к коду должны быть помогите собрать простой, но полный поиск данных и сортировать решение без использования ViewBags.
Объяснение использования кода в нижней части сообщения.
Мой индексный указатель (где находятся скрытые элементы).Атрибут 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», который первоначально возвращает частичный вид _Activity в вышеприведенном зрения Index:
public ActionResult _Activity()
{
using (var context = new ApplicationDbContext())
{
//create new LogModel object. this holds all that will be returned to the view
LogModel logModel = new LogModel();
//create new LogSelect object. this is the list of drop downs for the activity log table.
LogSelect logSelect = new LogSelect();
//query to get initial set
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 }; //this could bring back null user objects
//populate items for drop down lists
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();
//initial page for pagination is 1, default page size is 10.
int pageIndex = 1;
int pageSize = 10;
//return view with paginated list.
PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize);
//fill view model.
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 для обработки событий:
/**********************************************************************************************
_Activity.cshtml
/*********************************************************************************************/
//activity log sort buttons.
$('#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);
});
//this function checks and sets the "sort" attribute of the passed element.
//then based on setting of the "sort" attribute, returns a string value that will be used by code-behind to sort values in the table.
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())
{
//create new LogModel object. this holds all that will be returned to the view
LogModel logModel = new LogModel();
//create new LogSelect object. this is the list of drop downs for the activity log table.
LogSelect logSelect = new LogSelect();
//query
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 }; //this could bring back null user objects.
//populate items for drop down lists
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();
//filters
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); }
//always default sorting by date desc
result = result.OrderByDescending(r => r.Log.LogDate);
//sorting (any selection other than date sorting will be sorted secondarily by date descending)
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;
}
//turn result into paginated list
PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize);
//fill view model.
logModel.LogSelect = logSelect;
logModel.UserActivity = pgList;
//return model to the view
return PartialView("_Activity", logModel);
}
}
Пояснение:
При нажатии <a id="log-dropdown-user-sort"><img.../></a>
в частичном виде _Activity
, в яваскрипта нажмите событие $('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {}
срабатывает и вызывает функцию setSort(DOM element, string)
.
setSort()
функция устанавливает атрибут переданного элемента "sort"
, переключая значение атрибута между 'asc'
и 'desc'
, таким образом, влиять на будущее логического потока в пределах функции, и возвращает сцепленное строковое значение, которое будет использоваться в качестве параметра sortOrder
в GetActivity
GET, который называется следующим.
Метод GetActivity
GET затем, разумеется, запрашивает и возвращает данные, отсортированные по аргументу sortOrder
, вычисленному по инструкции switch
.
Итак, для каждого дополнительного заголовка я бы создал новое значение ViewBag и добавил его в оператор switch? –
Правильно, до сих пор все это использовалось в моих проектах и работало как шарм. Надеюсь, это поможет вам встать на вашем пути. –