对筛选列表进行排序

Sorting a filtered list

我有一个正在向用户显示的报告列表。我有 a-tags 允许列表以不同的方式排序(最后发布,最高投票等),我还有单独的 a-tags 根据特定的报告变量过滤列表(报告状态为打开,关闭等)。

我正在想办法让过滤器在按下用于对列表进行排序的 a 标签时保持原位,反之亦然。

我尝试过使用 statusId(id 设置为过滤列表)和 sortString(包含字符串"highest_award""last_update", 用于在 HomeController 中对列表进行排序),但我的想法是完全关闭。

有没有一个干净的方法来解决这个问题?

Index.cshtml

//List of sorting options -- *These are links that allow the user to sort the list as appropriate*
<ul class="nav nav-pills flex-column">
    <li><a asp-area="" asp-controller="Home" asp-action="Index" asp-route-sortString="@ViewData["AwardSort"]">Highest Awarded</a></li>
    <li><a asp-area="" asp-controller="Home" asp-action="Index" asp-route-sortString="@ViewData["UpdateSort"]">Last Updated</a></li>    
</ul>

...

//Filtering options set to status.Id -- *These are buttons that allow the user to filter the list as appropriate according to a set statusId for each article*
@foreach (ReportStatus status in Model.Statuses)
{
<li class="nav-item fs-5">
    <a class="nav-link" asp-area="" asp-controller="Home" asp-action="Index" asp-route-statusId="@status.Id">@status.StatusName</a>
</li>
}

...

//Report contents as viewed by used
@{
foreach (ReportViewModel report in Model.Reports.ReportViewModels)
{
    ...some "report" details
}

HomeController.cs (未提及过滤列表)

        public IActionResult Index(string sortString/*, int statusId*/)
        {
            Console.Write(sortString + " " + statusId + "\n");

            var reports = from r in _myRepository.GetAllReports()
                          select r;

            ViewData["AwardSort"] = String.IsNullOrEmpty(sortString) ? "highest_award" : "";
            ViewData["UpdateSort"] = String.IsNullOrEmpty(sortString) ? "last_update" : "";

            //reports = reports.Where(r => r.StatusId == statusId); -- Need to set this and keep set

            switch (sortString)
            {
                case "last_update":
                    reports = reports.OrderBy(r => r.DateOfUpdate);
                    break;
                case "highest_award":
                    reports = reports.OrderBy(r => r.NumberOfStars);
                    break;
            }

            HallOfFameViewModel hofViewModel = new HallOfFameViewModel(_myRepository.GetTopUsers(5));
            ReportListViewModel reportsViewModel = new ReportListViewModel(
                reports.ToList(),
                _myRepository.GetUserById(_userManager.GetUserId(User))
            );

            var model = new HomePageViewModel(hofViewModel, reportsViewModel, _myRepository.GetReportStatuses());
            return View(model);
        }

//-------------------------------------------
//The filtered list would be taken here, need to somehow add currently selected sort option as well as be able to set the sorting criteria

[ResponseCache(Duration = 2)]
        [Route("Home/Index/{id}")]
        public IActionResult Index(int statusId)
        {
            var reports = from r in _nemesysRepository.GetAllReports()
                          select r;

            HallOfFameViewModel hofViewModel = new HallOfFameViewModel(_nemesysRepository.GetTopUsers(10));
            ReportListViewModel reportsViewModel = new ReportListViewModel(
                _nemesysRepository.GetAllReportsWithStatus(statusId).ToList(),
                _nemesysRepository.GetUserById(_userManager.GetUserId(User))
            );

            var model = new HomePageViewModel(hofViewModel, reportsViewModel, _nemesysRepository.GetReportStatuses());
            return View(model);
        }



提前谢谢你。

我的朋友, 您还应该为您拥有的每个过滤器标签添加一个 'CurrentFilterName'。 例如:ViewData["AwardSort"] 应该与 ViewData["CurrentAwardSort"] 相结合 因此,当单击过滤器时页面重新加载时,您将值发送到此 'FilterName' 在输入值上,你输入 'CurrentFilteNameValue'。 希望这可以解决您的问题。祝你一切顺利:)

像下面这样更改您的代码:

public IActionResult Index(string sortString,int statusId)
{
    if (statusId!=0)
    {
        reports = test.Reports.ReportViewModels.Where(a => a.Id == statusId);
        var data = HttpContext.Session.GetString("Filter");
        if(data!=null)
        {
            sortString = data;
        }
    }
    else
    {
        ViewData["AwardSort"] = String.IsNullOrEmpty(sortString) ? "highest_award" : "";
        ViewData["UpdateSort"] = String.IsNullOrEmpty(sortString) ? "last_update" : "";
        if(sortString!=null)
        {
            HttpContext.Session.SetString("Filter", sortString);
        }
    }           
    switch (sortString)
    {
        case "last_update":
            reports = reports.OrderBy(r => r.DateOfUpdate);
            break;
        case "highest_award":
            reports = reports.OrderBy(r => r.NumberOfStars);
            break;
    }
    //....

    return View(model);
}

这是我的整个工作演示:

型号:

public class Test
{
    public Report Reports { get; set; }
    public List<ReportStatus> Statuses { get; set; }
}
public class ReportStatus
{
    public int Id { get; set; }
    public string StatusName { get; set; }
}
public class Report
{
    public IEnumerable<ReportViewModel> ReportViewModels { get; set; }
}
public class ReportViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateOfUpdate { get; set; }
    public int NumberOfStars { get; set; }
}

查看:

@model Test
<ul class="nav nav-pills flex-column">
    <li><a asp-area="" asp-controller="Home" asp-action="Index" asp-route-sortString="@ViewData["AwardSort"]">Highest Awarded</a></li>
    <li><a asp-area="" asp-controller="Home" asp-action="Index" asp-route-sortString="@ViewData["UpdateSort"]">Last Updated</a></li>
</ul>
@foreach (ReportStatus status in Model.Statuses)
{
    <li class="nav-item fs-5">
        <a class="nav-link" asp-area="" asp-controller="Home" asp-action="Index" asp-route-statusId="@status.Id">@status.StatusName</a>
    </li>
}
<table class="table">
    <tbody>
        @foreach (ReportViewModel report in Model.Reports.ReportViewModels)
        {
            <tr>
                <td>
                    @Html.DisplayFor(model => report.DateOfUpdate)
                </td>
                <td>
                    @Html.DisplayFor(model => report.NumberOfStars)
                </td>
            </tr>
        }
    </tbody>
</table>

控制器:

public class HomeController : Controller
{
    Test test = new Test()
    {
        Reports = new Report()
        {
            ReportViewModels = new List<ReportViewModel>()
            {
                new ReportViewModel(){ Id=1, DateOfUpdate=new DateTime(2018,2,12),NumberOfStars=34},
                new ReportViewModel(){Id=1,DateOfUpdate=new DateTime(2019,3,23),NumberOfStars=23},
                new ReportViewModel(){Id=2,DateOfUpdate=new DateTime(2014,5,13),NumberOfStars=25},
                new ReportViewModel(){Id=2,DateOfUpdate=new DateTime(2015,2,24),NumberOfStars=29}
            }
        },
        Statuses= new List<ReportStatus>()
        {
            new ReportStatus(){Id=1,StatusName="aa"},
            new ReportStatus(){Id=2,StatusName="bb"}
        }
    };
    public IActionResult Index(string sortString,int statusId)
    {
        var reports = test.Reports.ReportViewModels;

        if (statusId!=0)
        {
            reports = test.Reports.ReportViewModels.Where(a => a.Id == statusId);
            var data = HttpContext.Session.GetString("Filter");
            if(data!=null)
            {
                sortString = data;
            }
        }
        else
        {
            ViewData["AwardSort"] = String.IsNullOrEmpty(sortString) ? "highest_award" : "";
            ViewData["UpdateSort"] = String.IsNullOrEmpty(sortString) ? "last_update" : "";
            if(sortString!=null)
            {
                HttpContext.Session.SetString("Filter", sortString);
            }
        }           
        switch (sortString)
        {
            case "last_update":
                reports = reports.OrderBy(r => r.DateOfUpdate);
                break;
            case "highest_award":
                reports = reports.OrderBy(r => r.NumberOfStars);
                break;
        }
        test.Reports.ReportViewModels = reports;

        return View(test);
    }
}

一定要注册会话:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSession();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseSession();       
}

参考:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/app-state?view=aspnetcore-5.0#configure-session-state