让我为我的问题设置一些背景知识。我正在构建一个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 Skill
和Remove 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的新手。我正在使用这个项目来学习这些技术和正确的实践。
答案 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)