首页 > 解决方案 > ASP.NET Core - 使用下拉列表更新表格行

问题描述

我有一张包含游戏列表的表格。每行包含一个游戏 ID、一个包含所有游戏版本的下拉列表和一个当前显示最新版本状态的状态。

我想根据版本下拉列表值包含的内容更新表上的单行,这应该更改状态单元格的值。此更改还应更改ActiveVersion视图模型中的字段。

我认为这可以通过使用 AJAX、模型绑定和可能的部分视图来实现,但我不确定如何去做。

我试图通过使用字符串和整数作为数据类型的游戏版本控制来简化我的问题,因为我在我的 web 应用程序中使用复杂的模型和视图模型。

我有如下的 MVC 视图

@model IEnumerable<GameViewModel>
...
<tbody>
    @foreach (var item in Model)
    {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Id)
        </td>
        <td>
            @Html.DisplayFor(modelItem => @item.Versions.Where(x => x.Version == item.ActiveVersion).FirstOrDefault().Status)
        </td>
        <td>
            <select asp-for="@item.ActiveVersion" asp-items="@item.VersionsList"></select>
        </td>
    </tr>
    }
</tbody>

我的视图模型如下

public class GameViewModel
{
    public string Id { get; set; }
    public List<GameVersion> Versions { get; set; }
    public string ActiveVersion { get; set; }

    //Constructor - initialises active version to highest version
    public GameViewModel(Game game)
    {
        Id = game.Id;
        Versions = game.Versions;
        ActiveVersion = game.Versions.Max(x => x.Version).ToString();
    }

    //Returns a list of all versions to be used in dropdown
    public List<SelectListItem> VersionsList
    {
        get
        {
            List<SelectListItem> versionList = new List<SelectListItem>();
            foreach (GameVersion gv in Versions)
            {
               versionList.Add(new SelectListItem { Value = gv.Version.ToString(), Text = gv.Version.ToString() });
            }
            return versionList;
        }
    }
}

我的模型如下

public class GameVersion
{
    public int Version { get; set; }
    public string Status { get; set; }
}

public class Game
{
    public string Id { get; set; }
    public List<GameVersion> Versions { get; set; }
}

我正在使用 ASP.NET Core 3.1 开发 MVC webapp。

标签: javascriptc#ajaxasp.net-coreasp.net-core-mvc

解决方案


你可以使用jQuery来控制下拉列表的实现,根据你提供的模型动态更新状态的值。

这是一个工作演示,如下所示:

模型:

public class GameVersion
{
    public int Version { get; set; }
    public string Status { get; set; }
}

public class Game
{
    public string Id { get; set; }
    public List<GameVersion> Versions { get; set; }
}
public class GameViewModel
{
    public string Id { get; set; }
    public List<GameVersion> Versions { get; set; }
    public string ActiveVersion { get; set; }

    //Constructor - initialises active version to highest version
    public GameViewModel(Game game)
    {
        Id = game.Id;
        Versions = game.Versions;
        ActiveVersion = game.Versions.Max(x => x.Version).ToString();
    }

    //Returns a list of all versions to be used in dropdown
    public List<SelectListItem> VersionsList
    {
        get
        {
            List<SelectListItem> versionList = new List<SelectListItem>();
            foreach (GameVersion gv in Versions)
            {
                versionList.Add(new SelectListItem { Value = gv.Version.ToString(), Text = gv.Version.ToString() });
            }
            return versionList;
        }
    }
}

查看(索引.cshtml):

@model IEnumerable<GameViewModel>
<table>
    <tbody>
        @foreach (var item in Model)
        {
            <tr id="@item.Id">
                <td>
                    @Html.DisplayFor(modelItem => item.Id)
                </td>
                <td>
                    <span>

                        @*change this line*@

                        @Html.DisplayFor(modelItem => @item.Versions.Where(x => x.Version.ToString() == item.ActiveVersion).FirstOrDefault().Status)
                    </span>
                </td>
                <td>
                    <select class="activeVersion_@item.Id" asp-for="@item.ActiveVersion" asp-items="@item.VersionsList"></select>
                </td>
            </tr>
        }
    </tbody>
</table>

@section Scripts{
    <script>
        $(function () {
            var gameModel =@Json.Serialize(Model);
            $('*[class^="activeVersion"]').change(function () {
                var vers = $(this).find('option:selected').val()
                console.log(vers)
                var stat = $(this).parent().prev().find('span');
                stat.empty();
                var nodeid = $(this).attr('class').split('_')[1]
                $.each(gameModel, function (index, game) {
                    if (nodeid == game['id']) {
                        console.log(game['versions'])
                        $.each(game['versions'], function (indx, version) {
                            if (vers == version['version'])
                                stat.text(version['status'])
                        })
                    }
                })
            })
        })
    </script>
}

控制器(为了方便测试,我手动设置了值):

public IActionResult Index()
    {
        var games = new Game
        {
            Id = "game",
            Versions = new List<GameVersion> {
                new GameVersion{  Version=1,Status="Status1"},
                new GameVersion{  Version=2,Status="Status2"},
                new GameVersion{  Version=3,Status="Status3"},
            },
        };
        var games2 = new Game
        {
            Id = "game2",
            Versions = new List<GameVersion> {
                new GameVersion{ Version=4,Status="Status4"},
                new GameVersion{ Version=5,Status="Status5"},
                new GameVersion{ Version=6,Status="Status6"},
            },
        };
        var gameviewModels = new List<GameViewModel> {
            new GameViewModel(games),
            new GameViewModel(games2)
        };
        return View(gameviewModels);
    }

结果:

在此处输入图像描述


推荐阅读