一对多对多的razor模型绑定

问题描述 投票:0回答:1

我有一个名为 ChangeForm 的对象。 该对象有两个相关项,称为 ChangeType 和 ChangeFormChangeType。为了简洁起见,我只显示重要部分。

/* public class ChangeType {
    public Int16 ID { get; set; } = 0; // Primary Key
    public string Name { get; set; } = string.Empty;
    public bool IsSelected { get; set; } = false; // Other properties
} */
public class ChangeFormChangeType
{
public int _CfID { get; set; } //foreign key
public Int16 _CtID { get; set; }    //foreign key
}

public class ChangeForm
{
 public Int CfID {get;set;} = 0; PK
}

*/

在我的剃须刀页面上:

<div class="col-12 changeTypeList">
    @if (Model.ChangeTypeList != null && Model.ChangeTypeList.Any()) {
        @for (var i = 0; i < Model.ChangeTypeList.Count; i++) {
            <div style="vertical-align:top" class="form-check form-check-inline col-3">
                <input asp-for="@Model.ChangeTypeList[i].IsSelected" data-changetypeid="@Model.ChangeTypeList[i].ID" data-changetypeidlisttodisable="@Model.ChangeTypeList[i].ChangeTypeListToDisableOnSelection" class="form-check-input" type="checkbox" checked="@Model.ChangeTypeList[i].IsSelected" onchange="changeTypeSelectionChanged()" />
                <label asp-for="@Model.ChangeTypeList[i].IsSelected" class="form-check-label">@Model.ChangeTypeList[i].Name</label>
            </div>
        }
    } else {
        <span class="alert-danger">Could not load change type list.</span>
    }
</div>

所以我可以加载所有可能的更改类型。 但是我如何将选定的(选中的)项目存储在 ChangeFormChangeType 并让它在多个帖子中持续存在吗?我在后面的代码中有:

[BindProperty] 公共列表 SelectedChangeTypes { get;放; } = 新列表();

但我不确定如何在 .cshtml 文件中处理这个问题

我不想发布每个复选框更改事件...... 我最好只是在每个帖子上重建列表并添加一堆 HTML.HiddenFor 标签来表示我的 ChangeType 模型中的所有属性,然后简单地绑定它?

例如发布此作品:

/*

@Html.HiddenFor(model => Model.ChangeTypeList[i].ID)
@Html.HiddenFor(model => Model.ChangeTypeList[i].Name)
@Html.HiddenFor(repeated for other properties)

<input asp-for="@Model.ChangeTypeList[i].IsSelected" data-controlstodisable="@Model.ChangeTypeList[i].ChangeTypeListToDisableOnSelection" class="form-check-         input" type="checkbox" id="@Model.ChangeTypeList[i].ID" checked="@Model.ChangeTypeList[i].IsSelected" onchange="changeTypeSelectionChanged()" />
<label asp-for="@Model.ChangeTypeList[i].IsSelected" class="form-check-label">@Model.ChangeTypeList[i].Name</label>

*/

我希望能够将changeType中选定的项目存储在changeFormChangeType中,并通过多次回发保持它

asp.net-core razor model-binding
1个回答
0
投票

如果你的意思是设置所有选定的属性然后post,则tag-Helper

HTML.HiddenFor
方式是可行的,Javascript方式也是如此。您只需确保选择后保存到数据库即可。

ChangeForm.cshtml

@page
@model ChangeFormModel

<form method="post">
    <div class="col-12 changeTypeList">
        @if (Model.ViewModel.ChangeTypeList != null && Model.ViewModel.ChangeTypeList.Any())
        {
            @for (var i = 0; i < Model.ViewModel.ChangeTypeList.Count; i++)
            {
                <div style="vertical-align:top" class="form-check form-check-inline col-3">
                    <input asp-for="@Model.ViewModel.ChangeTypeList[i].IsSelected" data-changetypeid="@Model.ViewModel.ChangeTypeList[i].ID" class="form-check-input change-type-checkbox" type="checkbox" onchange="changeTypeSelectionChanged(this)" />
                    <label asp-for="@Model.ViewModel.ChangeTypeList[i].IsSelected" class="form-check-label">@Model.ViewModel.ChangeTypeList[i].Name</label>
                    <input type="hidden" name="SelectedChangeTypes[@i].CtID" value="@Model.ViewModel.ChangeTypeList[i].ID" />
                    <input type="hidden" name="SelectedChangeTypes[@i].IsSelected" value="@Model.ViewModel.ChangeTypeList[i].IsSelected" class="hidden-is-selected" />
                </div>
            }
        }
        else
        {
            <span class="alert-danger">Could not load change type list.</span>
        }
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

@section Scripts {
    <script>
        function changeTypeSelectionChanged(checkbox) {
            var isSelected = checkbox.checked;
            var parentDiv = checkbox.closest('div');
            var hiddenField = parentDiv.querySelector('.hidden-is-selected');
            hiddenField.value = isSelected;
        }
    </script>
}

ChangeForm.cshtml.cs

public class ChangeFormModel : PageModel
{
    private readonly WebApplication78.Data.WebApplication78Context _context;
    public ChangeFormModel(WebApplication78.Data.WebApplication78Context context)
    {
        _context = context;
    }

    [BindProperty]
    public ChangeFormViewModel ViewModel { get; set; } = new ChangeFormViewModel();

    public void OnGet()
    {
        // Load data
    }

    public IActionResult OnPost()
    {
        foreach (var selectedChangeType in ViewModel.SelectedChangeTypes)
        {
            if (selectedChangeType.IsSelected)
            {
                // Add to ChangeFormChangeType
            }
            else
            {
                // Remove from ChangeFormChangeType if needed
            }
        }

        // Save to database
        // Data is saved after you finished the properties selected

        return RedirectToPage("Success");
    }
}

或者,如果您打算选择然后执行其他操作,例如导航到其他页面以选择其他一些属性,您可以尝试本地存储或cookie。

        [BindProperty]
        public ChangeFormViewModel ViewModel { get; set; } = new ChangeFormViewModel();

        private const string CookieKey = "SelectedChangeTypes";

        public void OnGet()
        {
            // Load data
            var cookieValue = Request.Cookies[CookieKey];
            if (!string.IsNullOrEmpty(cookieValue))
            {
                var selectedChangeTypes = JsonConvert.DeserializeObject<List<ChangeFormChangeType>>(cookieValue);
                foreach (var changeType in ChangeFormViewModel.ChangeTypeList)
                {
                    var sessionItem = selectedChangeTypes.FirstOrDefault(s => s.CtID == changeType.ID);
                    if (sessionItem != null)
                    {
                        changeType.IsSelected = sessionItem.IsSelected;
                    }
                }
            }
        }

如果您的 lcoalstorage 或 cookie 未清除,则将保留所选状态。然后一起保存到数据库。

enter image description here

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