在发布到编辑控制器/视图时捕获文本区域内容

本文关键字:文本 区域 视图 编辑 控制器 | 更新日期: 2023-09-27 18:15:49

我有一个类型为List<ReviewGroupViewModel>的模型,其中ReviewGroupViewModel为:

public class ReviewGroupViewModel
{
    public string Country { get; set; }
    public List<Review> Reviews { get; set; }
}

在我的索引。在cshtml视图中,我使用嵌套的for循环迭代该模型,并为每个ReviewGroupViewModel(按ReviewGroupViewModel.Country分组)构建一个表。最终,每个Review对象在表中都有一行。每行的Commentary字段使用TextAreaFor HTML帮助器显示,允许用户输入文本:

Index.cshtml

@using (Html.BeginForm("Save", "Review", FormMethod.Post))
{
    for (var i = 0; i < Model.Count; i++)
    {
        <h6>@Html.DisplayFor(m => m[i].Country)</h6>
        <table class="table table-bordered table-condensed">
            <tr>
                <th style="text-align: center">
                    @Html.DisplayNameFor(m => m[i].Reviews[0].Commentary)
                </th>
                <th style="text-align: center">
                    Actions
                </th>
            </tr>
            @for (var j = 0; j < Model[i].Reviews.Count; j++)
            {
                <tr>
                    <td style="text-align: center">
                        @Html.TextAreaFor(m => m[i].Reviews[j].Commentary)
                    </td>
                    <td style="text-align: center">
                        @Html.ActionLink("Edit", "Edit", new { tempId = Model[i].Reviews[j].TempId }) |
                        @Html.ActionLink("Delete", "Delete", new { tempId = Model[i].Reviews[j].TempId })
                    </td>
                </tr>
            }
        </table>
    }
}

这是一个表单的边界,它是在点击页面上其他地方的"保存"按钮时提交的。

现在让我们假设用户在Index视图中的一个(或多个)文本区域中键入一些文本,然后继续单击给定表行的"Actions"中的"Edit"。这个文本然后丢失,因为我只是传递一个Id(类型:int)到我的编辑控制器方法。问题是,当导航到其他视图进行编辑/删除等操作时,我如何不丢失这个输入的文本(对于这个Review对象和索引视图中的所有其他对象)?

老实说,你不能直接将一个复杂的对象从视图传递给控制器方法。显然也不能嵌套HTML表单。当然,这是一个常见的场景,但我如何在代码中处理它?

在发布到编辑控制器/视图时捕获文本区域内容

你的问题是ActionLink。它生成一个简单的超链接。超链接将向服务器发送GET请求。并且不能在GET请求的主体中放置复杂的对象。

你需要这样做:带有2个提交按钮/动作的表单

for循环中的代码应该放在编辑器模板中。

@using (Html.BeginForm("Save", "Review", FormMethod.Post))
{
    for (var i = 0; i < Model.Count; i++)
    {
        @Html.EditorFor(m => Model[i], "MyTemplateName");
    }
}

在View文件夹中创建名为EditorTemplates的文件夹,并创建名为MyTemplateName的视图。通过将单个模型传递给视图,您可以在其中拥有迭代的每个单个项目的代码。

MyTemplateName.cshtml

@model Review
<h6>@Html.DisplayFor(m => m.Country)</h6>
        <table class="table table-bordered table-condensed">
            <tr>
                <th style="text-align: center">
                    @Html.DisplayNameFor(m => m.Reviews[0].Commentary)
                </th>
                <th style="text-align: center">
                    Actions
                </th>
            </tr>
            @for (var j = 0; j < m.Reviews.Count; j++)
            {
                // Here you should have different editor template... see the pattern :)
                @Html.EditorFor(m => m.Reviews[j], "MySecondTemplate")
            }
        </table>

希望这些信息对你有帮助。