可重复使用的复选框部分视图

时间:2015-01-15 15:35:56

标签: c# asp.net-mvc checkbox partial

我有一个局部视图,它使用带有字符串的列表(CheckBoxModel)和一个bool来创建一个复选框列表(CheckBoxModel)。该代码用于创建复选框,并在页面发布时将选定的复选框发送回控制器。我试图找到一种方法使我的部分可重用。正如您在代码中看到的那样,我发送部分完整模型,这可以在页面发布时获取更新的复选框。我试图发送我的Model的CheckBoxListModel,但它不起作用,因为当它创建复选框时,名称不正确。我想通过发送一个CheckBoxListModel来重用partial,所以每次我需要一组复选框时我都不必创建一个单独的部分。

我尝试将change_CheckBoxListPartial.cshtml改为

    @model MySite.Models.ViewModels.CheckBoxListModel
    ...
    @Html.EditorFor(x => x.CheckBoxes)
    ...

但没有clmReturnOptions,复选框名称最终为name =" CheckBoxes [0] .isChecked"而不是name =" clmReturnOptions.CheckBoxes [0] .isChecked"因此,当页面发布并返回控制器时,它们不会在模型中更新。

我一直在关注:http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/但似乎无法让复选框工作而不会将整个模型发送给我的部分。

CheckBoxListModel.cs

        public class CheckBoxListModel: ICheckBoxList
        {
            public IList<CheckBoxModel> CheckBoxes { get; set; }
            public string CheckBoxListTitle { get; set; }

            public CheckBoxListModel()
            {
            }
        }

        public class CheckBoxModel
        {
            public string CheckBoxName { get; set; }
            public string DisplayName { get; set; }
            public bool isChecked { get; set; }

            public CheckBoxModel()
            { }

            public CheckBoxModel(string checkboxname, string displayname, bool ischecked)
            {
                CheckBoxName = checkboxname;
                DisplayName = displayname;
                isChecked = ischecked;
            }
        }

        public interface ICheckBoxList
        {
            IList<CheckBoxModel> CheckBoxes { get; set; }
            string CheckBoxListTitle { get; set; }
        }

ReportFilterViewModel.cs

        public class ReportFilterViewModel
        {
            public ReportFilterViewModel()
            {
                clmReturnOptions = new CheckBoxListModel();
            }

            public CheckBoxListModel clmReturnOptions { get; set; }
        }

filters.cshtml&lt; - 这是部分被称为

的地方
    @model MySite.Areas.Reports.Models.ViewModels.ReportFilterViewModel
    ...
        @if (Model.Filters.IsReturnsOptionsAvailable)
        {
            Html.RenderPartial("_CheckBoxFilterPartial", Model.clmReturnOptions);
        }
    ...

_CheckBoxFilterPartial.cshtml

    @model MySite.Areas.Reports.Models.ViewModels.ICheckBoxList

    @{
        Layout = null;
    }

    <!DOCTYPE html>
    <html>
    <head>
        <title>Returns Options</title>
    </head>
    <body>
        <div class="col-md-4">
            <div class="plm prm ptm pbm configureCellSplitBG configureCellSplitBG-outline mtm">
                <div class="row mlm mrm">
                    <h6>@Model.CheckBoxListTitle</h6>
                </div>
                @Html.EditorFor(x => x.CheckBoxes)
            </div>
        </div>
    </body>
    </html>

CheckBoxModel.cshtml

    @model MySite.Areas.Reports.Models.ViewModels.CheckBoxModel
    <div class="row mlm mrm">
        <div class="form-group">
            <label class="checkbox">
                @Html.CheckBoxFor(x => x.isChecked, new { @data_toggle = "checkbox" })
                @Html.LabelFor(x => x.CheckBoxName, Model.DisplayName)
                @Html.HiddenFor(x => x.CheckBoxName)
            </label>
        </div>
    </div>

更新 当我查看源代码时,我可以看到CheckBox名称仍然是:name="CheckBoxes[0].isChecked" 因此,当模型返回到控制器时,列表为空

我做的另一个更改是将CheckBoxListModel.cs从MySite.Models.ViewModels移动到MySite.Areas.Reports.Models,因为其他所有内容都在reports.models下。

问题似乎是局部观点。如果我在主页中放置@Html.EditorFor(x => x.clmReturnOptions.CheckBoxes),则会使用全名创建复选框并正确更新。一旦我尝试在局部视图中使用EditorFor,复选框名称就会更改,并且指向它们的链接会返回到模型中断。我希望在局部视图中有这个,所以我不需要在任何地方添加所有ui格式我想要一个复选框列表。

我已更新上述代码

2 个答案:

答案 0 :(得分:0)

创建一个提供IList<CheckBoxModel>

访问权限的界面
public interface ICheckBoxList
{
    IList<CheckBoxModel> CheckBoxes { get; set; }
}

CheckBoxListModel实现该接口

public class CheckBoxListModel:ICheckBoxList
{...

您的_CheckBoxListPartial.cshtml局部视图将使用新界面作为其模型

@model MySite.Areas.Reports.Models.ViewModels.ICheckBoxList

并将EditorFor更改为

@Html.EditorFor(x => x.CheckBoxes)

我在您的问题中找不到显示您如何包含_CheckBoxListPartial局部视图的代码,但您只需传递ViewModel的clmReturnOptions属性(ReportFilterViewModel或其他)而不是整个模型。

你应该好好去。

答案 1 :(得分:0)

您需要将前缀传递给局部视图,以便正确命名元素

@if (Model.Filters.IsReturnsOptionsAvailable)
{
  Html.RenderPartial("_CheckBoxFilterPartial", Model.clmReturnOptions, new ViewDataDictionary
  {
    TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "clmReturnOptions" }
  })
}

您还可以编写自定义html帮助程序以使其更容易

public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
  string name = ExpressionHelper.GetExpressionText(expression);
  object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
  var viewData = new ViewDataDictionary(helper.ViewData)
  {
    TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = name }
  };
  return helper.Partial(partialViewName, model, viewData);
}

并用作

@Html.PartialFor(m => m.clmReturnOptions, "_CheckBoxFilterPartial")