【问题标题】:CheckboxList MVC EditorFor Template PostBackCheckboxList MVC EditorFor Template PostBack
【发布时间】:2015-11-06 06:12:56
【问题描述】:

我继承了一些不完整的代码。开发人员使用模板编辑器来创建他的复选框列表。问题是它没有绑定回模型,因此我可以将数据返回到服务器端。 任何人都有一个关于如何将 editorfortemplate 用于复选框列表并将数据发送回绑定到模型的示例? 以下是编辑器模板内容。

EDITOR TEMPLATE 称为 ServiceTypeViewModel.cshtml

     @model List<ViewModels.ServiceTypeViewModel>
<table>

@{int k = 0; int columns = 2;}

@for (int i = 0; i < (Model.Count / columns + (Model.Count % columns == 0 ? 0 : 1)); i++)
{
    <tr>
    @for(int j = 0; j<columns; j++){
        <td>
            @if (k<Model.Count) { 
                <input name="ProvidedServices[@(k)].Name" id="ProvidedServices__@(k)__Name" type="hidden" value="@Model[k].Name">       
                <input name="ProvidedServices[@(k)].Selected" class="CB" id="ProvidedServices__@(k)__Selected" type="checkbox" value="true">
                <input name="ProvidedServices[@(k)].Selected" type="hidden" value="false">
                <input name="ProvidedServices[@(k)].ServiceTypeClass" id="ProvidedServices__@(k)__ServiceTypeClass" type="hidden" value="@Model[k].ServiceTypeClass">       
                <input name="ProvidedServices[@(k)].ServiceType" id="ProvidedServices__@(k)__ServiceType" type="hidden" value="@Model[k].ServiceType">       
                @Html.DisplayFor(m=>Model[k].Name)
                k++;
            }
        </td>
    }
    </tr>
}
</table>

模型如下

  public class ServiceTypeViewModel
    {
        public string ServiceTypeClass { get; set; }
        public string ServiceType { get; set; }
        public bool Selected { get; set; }
        public string Name { get { return ServiceTypeClass + " " + ServiceType; } }
    }
}

主模型中的EditorFor模板定义。

[UIHint("ServiceTypeViewModel")]
public List<ServiceTypeViewModel> ProvidedServices { get; set; }

Index.cshtml

    @Html.LabelFor(x => x.ProvidedServices)
    @Html.EditorFor(x => x.ProvidedServices) 

如何让它显示为列表?

我让它像上图一样在模板中呈现,但回发将 providerservices 返回为 null。下面的代码呈现了两列复选框。

@model List<ViewModels.ServiceTypeViewModel>
<table>
 @{int k = 0; int columns = 2;}

@for (int i = 0; i < (Model.Count / columns + (Model.Count % columns == 0 ? 0 : 1)); i++)
{
   <tr>
    @for(int j = 0; j<columns; j++){
     <td>
   @if (k<Model.Count) { 
    @Html.HiddenFor(m => m[k].Name);
    @Html.HiddenFor(m => m[k].ServiceTypeClass);
    @Html.HiddenFor(m => m[k].ServiceType);
    @Html.CheckBoxFor(m => m[k].Selected);
    @Html.DisplayFor(m => m[k].Name);
  k++;
      }
        </td>
    }
    </tr>
  }
</table>

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


    【解决方案1】:

    ServiceTypeViewModel.cshtml更改为

    @model ViewModels.ServiceTypeViewModel
    
    <tr>
      <td>
        @Html.HiddenFor(m > m.ServiceTypeClass)
        @Html.HiddenFor(m > m.ServiceType)
        @Html.CheckBoxFor(m > m.Selected)
        @Html.DisplayFor(m => m.Name)
      </td>
    </tr>
    

    并确保其位于/Views/Shared/EditorTemplates 文件夹(或/Views/yourConrollerName/EditorTemplates 文件夹)中

    旁注:不清楚您的变量 kcolumns 应该做什么,但此编辑器模板将为您的集合中的每个项目生成正确的 html

    编辑(基于修改后的问题)

    如果您想要 2 列布局,则修改模板以使用 &lt;div&gt; 元素并使用 css 设置样式

    @model ViewModels.ServiceTypeViewModel
    <div>
      @Html.HiddenFor(m > m.ServiceTypeClass)
      ....
    </div>
    

    在主视图中

    <div id="container">
      @Html.EditorFor(x => x.ProvidedServices) 
    </div>
    

    和css

    #container div {
      width: 50%;
      display: inline-block;
      float: left;
    }
    

    这将产生一个 2 列,如 this fiddle 所示

    或者,如果您确实想使用表格(由于表格用于表格数据,它并不适合),那么您不能使用EditorTempate。相反,您需要在主视图中使用 for 循环

    <table>
      <tr>
        @for(int i = 0; i < Model.ProvidedServices.Count; i++)
        {
          <td>
            @Html.HiddenFor(m => m.ProvidedServices[i].ServiceTypeClass)
            @Html.HiddenFor(m => m.ProvidedServices[i].ServiceType)
            @Html.CheckBoxFor(m => m.ProvidedServices[i].Selected)
            @Html.LabelFor(m => m.ProvidedServices[i].Selected, Model.ProvidedServices[i].Name)
          </td>
          if((i + 1) % 2 == 0)
          {
            @:</tr><tr>
          }
        }
      </tr>
    </table>
    

    旁注:包含属性Name 的隐藏输入有点毫无意义。它是一个只读属性(没有设置器),因此无论如何它都不会被绑定。

    【讨论】:

    • 我更新了问题。你能帮我把它渲染成如图所示的列表吗?
    • 当然可以,但您不能为此使用EditorTemplate。您需要在视图中使用 for 循环,以便每行生成 2 列。现在没时间(很晚了),但会在早上更新答案。
    • 但是为了让你开始,看看this DotNetFiddle
    • 其实你可以使用EditorTemplate,但使用&lt;div&gt;元素而不是&lt;td&gt;,并设置样式(例如display:inline-block; float; left; width: 40%;
    • 我让它在编辑器模板中呈现,但提供服务的列表在回发时为空。我会更新问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-02
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    相关资源
    最近更新 更多