如何在 Ajax.BeginForm() 中手动设置 属性 值

How to manually set property value in Ajax.BeginForm()

我已经分享了下面的视图和视图模型。我通过使用 foreach 循环而不是使用某些 @Html 帮助程序填充了一个缩进的 select 列表(使用 optgroup)。但是,我不知道如何将列表中的 selected 值分配给 CreateMainEntryViewModel 的特定 属性。更具体地说,我需要根据提交表单时在下拉列表中创建的 selection 设置 DiscussionWallIdTimeFrameId 属性 值。在此任务中,我使用 Ajax.BeginForm() :

@model EcholuMvc.Models.CreateMainEntryViewModel
@using (Ajax.BeginForm("CreateMainEntry", "MainEntry", new AjaxOptions
{     
    UpdateTargetId = "div_MainEntries",
    InsertionMode = InsertionMode.Replace
}))
{       

     @Html.TextBoxFor(m => m.Title, new { placeholder = "Write a brief title...", @class = "form-control input-lg" })

     @Html.TextAreaFor(m => m.Content, new { placeholder = "Type your entry here...", @class = "form-control mainEntryField" })

     <label for="drp_DiscussionWallListForNewMainEntry" style="text-align:right" class="col-sm-3 control-label">Choose the Discussion Wall:</label>

     <select id="drp_DWListForNewMainEntry" class="form-control">
     @{
          foreach (DiscussionWall dw in Model.DiscussionWalls)
          {
               <optgroup label="@dw.WallTitle">
               foreach (TimeFrame tf in dw.TimeFrames)
               {
                  <option data-dw="@dw.WallId" data-tf="@tf.TimeFrameId">@tf.TimeFrameName</option>
               }              
                </optgroup>
         }
     }
     </select>

    <button type="submit" id="btn_SubmitNewPost">Post</button>                           

}

这是视图模型:

public class CreateMainEntryViewModel
{

    public string Title { get; set; }

    public string Content { get; set; }

    public Boolean IsAnonymous { get; set; }

    public int DiscussionWallId { get; set; }

    public int TimeFrameId { get; set; }

    public CreateMainEntryViewModel(List<DiscussionWall> walls)
    {
        DiscussionWalls = walls;
    }

    public List< DiscussionWall> DiscussionWalls { get; set; }
}

感谢任何帮助!

要直接回答您的问题,您需要为 DiscussionWallId 属性 添加一个隐藏输入,为 <select> 元素添加一个 name 属性,并且 value 属性为其 <option> 元素,并使用 javascript/jquery 根据所选选项更新隐藏输入的值。

@Html.HiddenFor(m => m.DiscussionWallId) // add
<select name="TimeFrameId" id="TimeFrameId" class="form-control"> // add name attribute
@{
  foreach (DiscussionWall dw in Model.DiscussionWalls)
  {
    <optgroup label="@dw.WallTitle">
      foreach (TimeFrame tf in dw.TimeFrames)
      {
        <option data-dw="@dw.WallId" value="@tf.TimeFrameId">@tf.TimeFrameName</option> // modify
      }              
  </optgroup>
}
</select>

并更新隐藏输入的值

$('#TimeFrameId').change(function() {
    var dw = $(this).children('option:selected).data('dw');
    $('#DiscussionWallId').val(dw);
});

当您提交表单时,DiscussionWallIdTimeFrameId 属性现在都将被绑定。

然而,添加隐藏输入(和您的 data-dw 属性)是不必要的(恶意用户可以轻易更改隐藏输入的值,可能导致您的应用程序失败)。如果出于任何原因您需要 DiscussionWallId 属性 与所选 TimeFrame 相关联,那么您应该根据 TimeFrameId.[= 的值从存储库中获取该值30=]

还有很多其他原因导致这是一个糟糕的设计,包括您没有获得强类型的双向模型绑定,并且您无法使用内置的客户端验证功能。

如果您使用 MVC-5.2,那么您可以使用 SelectListItem, or the overloads of SelectList that accepts a dataGroupField value to generate an IEnumerable<SelectListItem> that supports grouped options in the view and then simply use the strongly typed @Html.DropDownListFor() helper. However this is really only suitable if you have a few DiscussionWalls objects, and each one contains only a few TimeFrame objects. If not, then you should be implementing cascading dropdownlists. For an example, refer and this DotNetFiddleGroup 属性。