如何根据 ASP.NET Core 中先前的 selection 更改 select 选项

How to change select options based on previous selection in ASP.NET Core

我正在使用 ASP.NET Core 3.1 MVC 绑定 dropdown/select 工作流状态。

工作流状态的示例是 - OpenScheduledClosed 等。所有这些在 UI.

中正确显示

现在我必须添加一些不同的逻辑,以便这些状态选项是基于当前存储状态的动态。

例如,如果当前存储的工作流状态是 Scheduled 那么用户不能 see/select Open 而只能 关闭.

同样,如果当前工作流状态是 Closed 那么用户不应该 see/select Scheduled 而只是 打开.

因此,每个状态都有某种链接状态,用户可以在其中进行下一步。

请建议我如何做到这一点。

谢谢。

For instance, if current workflow state stored is Scheduled then user cannot see/select Open but just Closed.

Similarly, if current workflow state is Closed then user should not see/select Scheduled but just Open.

So, each state has some sort of linked states where user can go next.

如果只显示一条带有工作流状态的记录,在控制器中,可以使用switch语句根据当前状态过滤工作流状态,然后使用ViewBag或ViewData将过滤状态传递给视图页面并绑定 select 元素。

如果您要显示带有工作流状态的多条记录,您可以使用下拉列表 select 选项创建一个视图模型。

请参考下面的示例,在这个示例中,当页面加载时,它会根据当前状态过滤状态,然后在改变状态后,它会使用 JQuery Ajax 来更新 DropDownList 选项:

public class WorkFlowState
{
    public int ID { get; set; }
    public string State { get; set; }
}

public class Article
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string SelectedState { get; set; } 
}
public class ArticleViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string SelectedState { get; set; }
    public List<WorkFlowState> States { get; set; }
}

控制器:

    private readonly IDataRepository _repository;
    public ArticleController(IDataRepository dataRepository)
    {
        _repository = dataRepository;
    }

    public IActionResult Index()
    {
        //query database to get all article with state.
        var articles = new List<Article>(){
            new Article() { Id = 1, Name = "A", SelectedState = "Open" },
            new Article() { Id = 2, Name = "B", SelectedState = "Scheduled" },
             new Article() { Id = 3, Name = "C", SelectedState = "Closed" },
        };

        //get all states: Open, Scheduled, Closed.
        var allstate = _repository.GetWorkFlowStates();

        //based on the article current state to set the Dropdownlist select items:
        var articlelist = articles.Select(c => new ArticleViewModel()
        {
            Id = c.Id,
            Name = c.Name,
            SelectedState = c.SelectedState,
            States =
               c.SelectedState == "Scheduled" ? allstate.Where(d=>d.State != "Open").ToList():
               c.SelectedState == "Closed" ? allstate.Where(d=>d.State !="Scheduled").ToList():
               allstate.ToList()
        }); 
          
        return View(articlelist);
    }
    [HttpPost]
    public IActionResult GetStates(string selectedState)
    {
        //get all states
        var allstate = _repository.GetWorkFlowStates();
        //filter states
        switch (selectedState)
        {
            case "Scheduled":
                allstate = allstate.Where(d => d.State != "Open").ToList();
                break;
            case "Closed":
                allstate = allstate.Where(d => d.State != "Scheduled").ToList();
                break;
        }

        return Json(allstate);
    }

查看页面:

@model IEnumerable<Core3_1MVC.Models.ArticleViewModel>

@{
    ViewData["Title"] = "Index";
}

<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Id)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.SelectedState)
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Id)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                <select asp-for="@item.SelectedState" asp-items="@(new SelectList(item.States, "State", "State"))"> 
                </select>
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
                @Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
                @Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
            </td>
        </tr>
}
    </tbody>
</table>

@section Scripts{ 

<script>  
    $(function () {
        $("select").each(function (index, item) {
            $(item).change(function () {
                var selectedstate = $(this).val();
                var ddl = $(this);
                $.ajax({
                    url: "/Article/GetStates",
                    method: "Post",
                    data: { "selectedState": selectedstate },
                    success: function (result) {
                        ddl.empty(); //clear the options:
                        var s = "";
                        for (var i = 0; i < result.length; i++) {
                            s += '<option value="' + result[i].state + '">' + result[i].state + '</option>';
                        }
                        ddl.html(s);
                    }
                });
            });
        });
    });
</script>
}

结果如下: