You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ViewModel实现MVC列表视图可点击表头排序(禁用ViewBag)

实现MVC表格表头点击排序(无需ViewBag)

嘿,我来帮你搞定这个表头排序的需求,完全不用ViewBag,就用你现有的SortModel就能实现。咱们一步步来:

首先,先修正你控制器里的小问题——你原来的排序代码只是生成了排序后的序列,但没把结果赋值回docs,而且只处理了Age降序的情况,咱们完善一下:

public ActionResult Index(SortModel model)
{
    var docs = db.GetDocs().ToList(); // 先获取基础文档数据

    // 处理排序逻辑
    if (!string.IsNullOrEmpty(model.SortParameter))
    {
        switch (model.SortParameter)
        {
            case "Age":
                docs = model.SortOrder == "desc" 
                    ? docs.OrderByDescending(x => x.Age).ToList() 
                    : docs.OrderBy(x => x.Age).ToList();
                break;
            case "Name":
                docs = model.SortOrder == "desc" 
                    ? docs.OrderByDescending(x => x.Name).ToList() 
                    : docs.OrderBy(x => x.Name).ToList();
                break;
            // 以后要加其他字段排序,直接在这里加case就行
        }
    }
    else
    {
        // 设置默认排序:比如按Name升序
        docs = docs.OrderBy(x => x.Name).ToList();
        model.SortParameter = "Name";
        model.SortOrder = "asc";
    }

    model.Documents = docs; // 把排序后的数据赋值回ViewModel
    return View(model);
}

接下来是视图部分,把原来的表头改成可点击的ActionLink,点击时自动传递SortParameter和SortOrder参数给控制器,更新ViewModel:

@{
    // 写个小辅助方法,用来判断下一次点击的排序方向
    string GetSortOrder(string currentParam, string targetParam, string currentOrder)
    {
        // 如果当前已经是按目标字段升序,就切换成降序,否则默认升序
        return currentParam == targetParam && currentOrder == "asc" ? "desc" : "asc";
    }
}

<table>
    <thead>
        <tr>
            <th>
                @Html.ActionLink(
                    // 显示字段的DisplayName
                    Html.DisplayNameFor(model => model.Documents[0].Name).ToString(),
                    // 指向的Action方法
                    "Index",
                    // 传递的参数,对应SortModel的属性
                    new 
                    { 
                        SortParameter = "Name",
                        SortOrder = GetSortOrder(Model.SortParameter, "Name", Model.SortOrder)
                    }
                )
                <!-- 可选:显示当前排序方向的小箭头 -->
                @if (Model.SortParameter == "Name")
                {
                    @(Model.SortOrder == "asc" ? " ↑" : " ↓")
                }
            </th>
            <th>
                @Html.ActionLink(
                    Html.DisplayNameFor(model => model.Documents[0].Age).ToString(),
                    "Index",
                    new 
                    { 
                        SortParameter = "Age",
                        SortOrder = GetSortOrder(Model.SortParameter, "Age", Model.SortOrder)
                    }
                )
                @if (Model.SortParameter == "Age")
                {
                    @(Model.SortOrder == "asc" ? " ↑" : " ↓")
                }
            </th>
        </tr>
    </thead>
    <tbody>
        <!-- 遍历显示文档数据 -->
        @foreach (var item in Model.Documents)
        {
            <tr>
                <td>@Html.DisplayFor(modelItem => item.Name)</td>
                <td>@Html.DisplayFor(modelItem => item.Age)</td>
            </tr>
        }
    </tbody>
</table>

你的ViewModel完全不用改,保持原来的结构就行:

public class SortModel 
{ 
    public List<Document> Documents { get; set; } 
    public string SortParameter { get; set; } 
    public string SortOrder { get; set; } 
} 

public class Document 
{ 
    public string Name { get; set; } 
    public int Age { get; set; } 
}

原理很简单:点击表头的ActionLink时,会把对应的SortParameter(比如"Name"或"Age")和计算好的SortOrder(asc/desc)作为参数传递给Index控制器方法,控制器根据这两个参数对数据排序,再把排序后的数据赋值回ViewModel,最后返回视图刷新页面。

这样就完全不用ViewBag,所有状态都通过ViewModel来维护啦!

内容的提问来源于stack exchange,提问作者woggles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:33:12