2

我有一个局部视图,我将模型传递给它,它显示用户可以选择的复选框,这最终会与我的表单一起发布,以便我可以查询它们的选中状态并根据需要将数据插入数据库。

我想更改我的局部视图,以便不采用包含模型列表的模型,而是直接采用模型列表,从而将其解耦并使其作为局部视图更有用。问题是当我这样做时,它似乎没有正确绑定数据。下面是之前的代码示例(正常工作和不工作之后)。

如果有人能够阐明为什么我的更改没有生效,我将不胜感激,即在我检查发布的数据时的后代码中,列表为空,而在正确填充之前:

前:

调用局部视图:

<fieldset>
    <legend>Facilities</legend>
    <div class="display-field">
        <div>
            @{Html.RenderPartial("Partial/FacilityPartial", Model);}
        </div>
    </div>
</fieldset>

部分观点:

@model namespace.Models.SchoolRegisterModel
@for (var i = 0; i < Model.Facilities.Count; i++)
{
    @Html.HiddenFor(x => x.Facilities[i].name)
    @Html.HiddenFor(x => x.Facilities[i].facility_id)
    @Html.LabelFor(x => x.Facilities[i].@checked, Model.Facilities[i].name);
    @Html.CheckBoxFor(
            x => x.Facilities[i].@checked,
        new
        {
            id = Model.Facilities[i].facility_id,
            @class = "RightSpacing",
            description = Model.Facilities[i].description
        }
    ) 
}

后:

调用局部视图:

<fieldset>
    <legend>Facilities</legend>
    <div class="display-field">
        <div>
            @{Html.RenderPartial("Partial/FacilityPartial", Model.Facilities);}
        </div>
    </div>
</fieldset>

部分观点:

@model IEnumerable<namespace.Models.facility>
@for (int i = 0; i < Model.Count(); i++)
{
    @Html.HiddenFor(x => x.ElementAt(i).name)

    @Html.HiddenFor(x => x.ElementAt(i).name)
    @Html.HiddenFor(x => x.ElementAt(i).facility_id)
    @Html.LabelFor(x => x.ElementAt(i).@checked, Model.ElementAt(i).name);
    @Html.CheckBoxFor(
            x => x.ElementAt(i).@checked,
        new
        {
            id = Model.ElementAt(i).facility_id,
            @class = "RightSpacing",
            description = Model.ElementAt(i).description
        }
    )
}

提前致谢!

完成的代码(工作)

模型:

public class SchoolRegisterModel
{
    // ... Lots of data 
    public string Data { get; set; }

    [Display(Name = "Facilities")]
    public IEnumerable<FacilityViewModel> Facilities { get; set; }
}

namespace namespace.Models
{
    public class FacilityViewModel
    {
        public FacilityViewModel()
        {
        }

        public FacilityViewModel(facility facil, bool bSelected = false)
        {
            this.Facility = facil;
            this.Selected = bSelected;
        }

        public facility Facility { get; set; }
        public bool Selected { get; set; }        
    }
}

编辑器模板:

@model namespace.Models.FacilityViewModel
@Html.HiddenFor(x => x.Facility.facility_id)
@Html.HiddenFor(x => x.Facility.name)
@Html.LabelFor(x => x.Selected, Model.Facility.name)
@Html.CheckBoxFor(x => x.Selected,
    new
    {
        id = Model.Facility.facility_id,
        @class = "RightSpacing",
        description = Model.Facility.description
    }
)

控制器:

// GET: /School/Register

public ActionResult Register()
{
    var viewModel = new SchoolRegisterModel();

    PopulateFacilityCollection(ref viewModel);
    return View(viewModel);
}

private void PopulateFacilityCollection(ref SchoolRegisterModel viewModel)
{
    List<FacilityViewModel> FacilityCollection = new List<FacilityViewModel>();
    foreach (facility facil in DBModel.facilities)
    {
        FacilityCollection.Add(new FacilityViewModel(facil));
    }

    viewModel.Facilities = FacilityCollection;
}

看法:

<fieldset>
    <legend>Facility</legend>
        <div class="editor-field">
            @Html.EditorFor(x => x.Facilities)
        </div>
</fieldset>

现在一切似乎都很好,我希望这对其他人有帮助!

4

1 回答 1

1

问题是,当您应该使用编辑器模板时,您似乎正在使用部分视图。使用 Partials 时,您需要传递完整的模型,以便 Html 助手在它生成的名称/ID 中保留完整的对象层次结构。由于模型绑定器在反序列化期间使用这些名称,如果层次结构丢失......数据无法重新饱和。

我建议改用编辑器模板,这将允许您在局部视图中保持 Razor 代码相同,同时仅传递顶级模型中所需的对象......在您的情况下是列表。

这是一个关于如何使用它们的非常好的教程:http: //coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

于 2013-02-15T20:41:58.650 回答