使用HTML Tag Helpers在MVC中动态添加行到HTML表

时间:2017-02-06 00:04:58

标签: javascript c# html razor asp.net-core-mvc

让我为我的问题设置一些背景知识。我正在构建一个asp.net核心mvc应用程序,其模型类似于下面的

public class Employee {
    public string Name { get; set; }
    public List<Skill> Skills { get; set; }
}

public class Skill {
    public string Name { get; set; }
    public int ExpertLevel { get; set; }
}

现在我不想要一个单独的页面来添加Skills。因此,在我Employee的视图(创建,编辑等)中,我想将List<Skill>表示为HTML表。现在在表格下方,我将使用几个按钮Add SkillRemove Skill。我的cshtml的相关部分如下所示

<table>
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Skills.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Skills.ExpertLevel)
            </th>
        </tr>
    </thead>

    <tbody>
        @if (Model.Skills != null) {
            @foreach (var item in Model.Skills) {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Name)
                        <input type="hidden" asp-for=@item.Name />
                        <span asp-validation-for=@item.Name class="text-danger" />
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ExpertLevel)
                        <input type="hidden" asp-for=@item.ExpertLevel />
                        <span asp-validation-for=@item.ExpertLevel class="text-danger" />
                    </td>
                </tr>}
        }
    </tbody>

</table>

这个剃刀代码转换为html,如下所示

<table>
    <thead>
        <tr>
            <th>Skill</th>
            <th>ExpertLevel</th>
        </tr>
    </thead>

    <tbody>
        <tr>
            <td>
                C#
                <input type="hidden" data-val="true" data-val-required="Skill Name is required" id="item_Name" name="item.Name" value="C#" />
                <span class="text-danger field-validation-valid" data-valmsg-for="item.Name" data-valmsg-replace="true" />
            </td>
            <td>
                Yes
                <input type="hidden" data-val="true" data-val-number="The field ExpertLevel must be a number." id="item_ExpertLevel" name="item.ExpertLevel" value="4.0" />
                <span class="text-danger field-validation-valid" data-valmsg-for="item.ExpertLevel" data-valmsg-replace="true" />
            </td>
        </tr>
    </tbody>

</table>

现在,我已经研究了如何添加行并使用javascript删除行,除了我使用普通的html动态构造行(如下所示)。

var tdStr = '';
$(rowId).children('td').each(function () {
    tdStr += '<td>' + $.trim($(this).children().first().val()) + '</td>';
});

var tr = $('<tr>' + tdStr + '</tr>');
$(tableId + ' > tbody:last-child').append(tr);

我不喜欢我必须手动创建具有所有相关属性的标签,例如data-val-required,class =“text-danger field-validation-valid”等。标签助手将真正帮助我提高我的代码质量。

我的问题是如何“构建”我的表行而不必硬编码我的模型DataAnnotations信息(如RequiredAttribute.ErrorMessage,DataTypeAttribute等)以及标记助手从{{1}推断出来的其他此类信息进入javascript

我正在玩Linq.Expression标签或“隐藏的tr”,但未能取得多大进展。

我是asp.net核心,mvc,html和javascript的新手。我正在使用这个项目来学习这些技术和正确的实践。

1 个答案:

答案 0 :(得分:0)

我想你可以像这样克隆模板记录:

<table id="TheTable">
    <thead>
        <tr>
            <th>Skill</th>
            <th>ExpertLevel</th>
        </tr>
    </thead>

    <tbody>
        <tr id="example">
            <td>
                <span data-template-field="fieldA">C#</span>
                <input  type="hidden" data-val="true" data-val-required="Skill Name is required" id="item_Name" name="item.Name" value="C#" />
                <span class="text-danger field-validation-valid" data-valmsg-for="item.Name" data-valmsg-replace="true" />
            </td>
            <td>
                <span data-template-field="fieldB">Yes</span>
                <input type="hidden" data-val="true" data-val-number="The field ExpertLevel must be a number." id="item_ExpertLevel" name="item.ExpertLevel" value="4.0" />
                <span class="text-danger field-validation-valid" data-valmsg-for="item.ExpertLevel" data-valmsg-replace="true" />
            </td>
        </tr>
    </tbody>

</table>

<button onclick="addLine('#TheTable')">add line</button>

和javascript代码:

addLine = function(tableId)
{
    var templaterow = $('#example');
    var clone = templaterow.clone(true)[0];    

    var fieldA = clone.querySelector('[data-template-field="fieldA"]');
    var fieldB = clone.querySelector('[data-template-field="fieldB"]');

    fieldA.innerText = "<new value>";
    fieldB.innerText = "123";

    $(tableId + ' > tbody:last-child').append(clone);   
}

如何制作示例记录取决于您。 您可以使用第一行,但如果您有一个空表,那么您将遇到问题,因此我认为最好添加一个不可见的表,其中只有一行包含一个虚拟记录,这样就可以了解布局。然后隐藏那张桌子。

祝你好运

(PS:示例使用jQuery https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js