使用单个链接对字段进行升序和降序排序

问题描述 投票:5回答:4

所以我有一个带有表的MVC应用程序,当单击标题时,我希望它根据单击的次数以升序或降序方式切换。

目前我只能降序或升序排序我不知道如何实现两者。当用户登录并且我正在使用交换机时,userName只是我从另一个控制器获得的变量,因为我计划有多个可以排序的标头。

View

<table>
    <tr>
        <th>
            <a href="@Url.Action("Dispatch", "Calls", new { userName = Session["UserName"], new { sortOrder = "Name_desc" })">Name</a>
        </th>
    </tr>
</table>

Controller

public ActionResult Index(string userName, string sortOrder)
{
    string userName = Session["UserName"].ToString();

    var model = from t in db.Users
                where t.UserName == userName
                select t;

    switch(sortOrder)
    {
        case "Name_desc":
            model = model.OrderByDescending(t => t.UserName);
            break;
    }
}
asp.net-mvc linq sorting asp.net-mvc-5
4个回答
9
投票

将排序顺序放在ViewBag值中。内联检查(Viewbag.NameSort):

视图:

<th>
    <a href="@Url.Action("Dispatch", "Calls", new { userName = Session["UserName"], new { sortOrder = ViewBag.NameSort })">Name</a>
</th>

控制器:

public ActionResult Index(string userName, string sortOrder)
{
    string userName = Session["UserName"].ToString();

    // Convert sort order
    ViewBag.NameSort = sortOrder == "Name" ? "Name_desc" : "Name";

    var model = from t in db.Users
                where t.UserName == userName
                select t;

    switch(sortOrder)
    {
        case "Name_desc":
            model = model.OrderByDescending(t => t.UserName);
            break;
        case "Name":
            model = modelOrderBy(t => t.UserName);
            break;
    }
}

2
投票

我不想使用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局部视图返回到上面的索引视图中:

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&nbsp;&nbsp;<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&nbsp;&nbsp;<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">&laquo;</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">&raquo;</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时,javascript单击事件$('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {}将触发并调用setSort(DOM element, string)函数。 setSort()函数设置传递元素的"sort"属性,在'asc''desc'之间切换属性值,从而影响函数中未来的逻辑流程,并返回一个串联的字符串值,该值将用作sortOrder GET方法中的GetActivity参数,这被称为下一个。 然后,GetActivity GET方法查询并返回基于sortOrder语句评估的switch参数排序的数据。


0
投票

只需在.js文件中输入代码 - “order”:[[6,“asc”]]。其中6代表列的placeNumber。例如1.id,2.name。等等


0
投票

对于Razor页面,我刚刚在页面模型中添加了一个if-else语句和一个“CurrentSortDir”var和“ToggleSortDir”var。

所以我的“index.cshtml”:

         <th>
            <a asp-page="./Index" 
            asp-route-sortOrder="ManufacturerPN"
            asp-route-sortDir = "@Model.ToggleSortDir">
                @Html.DisplayNameFor(model => model.Inventory[0].ManufacturerPN)
            </a>
          </th>

我的index.cshtml.cs:

public string CurrentSortDir { get; set; }
public string ToggleSortDir {get; set; }
public async Task OnGetAsync(string sortOrder, string sortDir, string currentFilter, string searchString, int? pageIndex)
    {
        CurrentSort = sortOrder;
        CurrentSortDir = sortDir;
  if (CurrentSortDir == "DESC")
        {
            ToggleSortDir = "ASC";
            switch (sortOrder)
            {
                case "ManufacturerPN":
                    Items = Items.OrderByDescending(s => s.ManufacturerPN);
                    break;
             ....
             }
         }
         else
         {
           ToggleSortDir = "DESC";
            switch (sortOrder)
            {
                case "ManufacturerPN":
                    Items = Items.OrderBy(s => s.ManufacturerPN);
                    break;
               ....
             }
           }

你最终会得到一个全局的排序方向......但我认为那没关系。否则,您需要为每列添加单独的var,然后在每种情况下添加if else。

© www.soinside.com 2019 - 2024. All rights reserved.