ASP.Net MVC动态输入绑定到相同的控制器属性 [英] ASP.Net MVC Dynamic input bound to same controller property

查看:76
本文介绍了ASP.Net MVC动态输入绑定到相同的控制器属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有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" of type="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 selected Type.

或具有两个带有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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆