ASP.Net MVC动态输入绑定到相同的控制器属性 [英] ASP.Net MVC Dynamic input bound to same controller property
问题描述
我有2个控制器字段,分别是类型"和数据". 根据要为类型"(日期或文本)选择的值,我想动态地将数据"字段显示为文本输入或自定义时间选择器输入. 由于任何时候都只能渲染一个,因此我需要使用相同的属性名称(Data)进行绑定. 这就是我正在尝试的:
I have 2 controller fields say Type and Data. Depending on value selected for Type (Date or Text), I want to display Data field dynamically as either a text input or a custom timepicker input. Since only one will be rendered at any time, I need to bind with the same property name (Data). This is what I am trying:
@if (Model.Type == "Date")
{
// custom timepicker control goes here
<input asp-for="Data" class="form-control timepicker"/>
}
else
{
<input asp-for="Data" class="form-control text-input" type="text"/>
}
在页面加载时,仅呈现文本输入,并且根据所选的类型显示/隐藏.时间选择器输入永远不会显示(根本不会生成html).
On page load only text input is rendered, and it shows/hides based on Type selected. The timepicker input is never displayed (the html is not generated at all).
有没有办法在MVC中实现这一目标?
Is there a way to achieve this in MVC?
推荐答案
不能有两个具有相同名称的<input>
元素.如果发布包含多个具有相同名称的输入的<form>
,则MVC模型绑定器将仅绑定来自最后一个输入的一个值.
You can not have two <input>
elements with the same name. If a <form>
containing multiple inputs with the same name is posted, the MVC model binder will only bind one value from the last input.
要实现您想要的目标,您有两个选择:
To achieve what you want, you have two options:
-
在视图中,只有一个输入的
name="Data"
为type="text"
,然后让时间选择器将时间作为字符串写入此输入.然后在控制器中,根据所选的Type
解析此输入值.
Either have only one input with
name="Data"
oftype="text"
in the View, and let the timepicker write the time as a string to this input. Then in the controller, parse this input value depending on the selectedType
.
或具有两个带有name="TextData"
和name="TimeData"
的输入,并根据所选的Type
使用JS禁用和隐藏这些输入之一.在控制器中,根据所选的Type
从右侧输入读取值.可以说这是更清洁的解决方案.
Or have two inputs with name="TextData"
and name="TimeData"
, and disable and hide one of these inputs using JS depending on the selected Type
. In the controller, read the value from the right input depending on the selected Type
. This is arguably the cleaner solution.
在MVC5中,第二个解决方案看起来像这样(我对MVC-Core并不熟悉):
In MVC5 the second solution would look like this (I am not familiar with MVC-Core):
@model MyViewModel
@using (Html.BeginForm("Submit", "MyController", FormMethod.Post)) {
@Html.EditorFor(m => m.Type)
@Html.EditorFor(m => m.TextData, new { @class = "text-input"})
@Html.EditorFor(m => m.TimeData, new { @class = "timepicker"})
}
<script type="text/javascript">
function toggleInput_() {
if ($('#@Html.IdFor(m => m.Type)').val() === 'Text') {
$('#@Html.IdFor(m => m.TextData)').prop('disabled', false).show();
$('#@Html.IdFor(m => m.TimeData)').prop('disabled', true).hide();
}
else {
$('#@Html.IdFor(m => m.TextData)').prop('disabled', true).hide();
$('#@Html.IdFor(m => m.TimeData)').prop('disabled', false).show();
}
}
$(document).ready(function() {
$('#@Html.IdFor(m => m.Type)').on('change', function() {
toggleInput_(); // toggle when drop down changes
});
toggleInput_(); // toggle initially on page load
});
</script>
控制器:
[HttPost]
public ActionResult Submit(MyViewModel postData) {
string textValue = null;
DateTime? timeValue = null;
if (postData.Type == "Text") {
textValue = postData.TextData;
}
else {
timeValue = postData.TimeData;
}
// ...
}
这篇关于ASP.Net MVC动态输入绑定到相同的控制器属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!