向ViewModel添加动态添加的控件

时间:2015-07-01 13:56:22

标签: c# asp.net-mvc viewmodel

我有以下ViewModel,我填写了一些预定义的数据。其中一个预定义数据是ApplicationParameter ViewModels列表,它被设置为最初显示n个ApplicationParameters。

我想要实现的是允许用户在单击按钮时添加额外数量的ApplicationParameters ViewModels,这是通过使用ApplicationParameter代码调用PartialView实现的。正如预期的那样,控件会自动添加,但它们在ViewModel中无法识别,因为它们没有正确的命名(因为它们是嵌套的)。

如何使动态添加的控件对POST返回的ViewModel可见。

的ViewModels

public class ApplicationVM
{

    public int idApplication { get; set; }
    public int idCompany { get; set; }
    public string Company { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string Link { get; set; }
    public string Photo { get; set; }

    public List<ApplicationParameterVM> ApplicationParameters { get; set; }
}

public class ApplicationParameterVM
{
    public string Name { get; set; }
    public bool Keep { get; set; }
}

操作视图(代码段)

 <tbody id="editorRows">
     @for (int i = 0; i < Model.ApplicationParameters.Count(); i++)
         {
            <tr>
                <td>
                    @Html.TextBoxFor(m => Model.ApplicationParameters[i].Name, new { @class = "form-control" })
                     @Html.CheckBoxFor(m => Model.ApplicationParameters[i].Keep)
                  </td>
              </tr>
           }
   </tbody>

添加ApplicationParameterVM的操作视图

   @model AccessMarketmind.Areas.Administration.ViewModels.ApplicationParameterVM
   @{
        Layout = null;
    }

<tr class="application-parameters">
     <td>
         @Html.TextBoxFor(m => Model.Name, new { @class = "form-control" })
         @Html.CheckBoxFor(m => Model.Keep)
     </td>
</tr>

我知道这个看起来微不足道,可以使用Javascript轻松完成,但问题是我有更复杂的ViewModels(读取:重度嵌套),其中Javascript不是一个选项。

2 个答案:

答案 0 :(得分:1)

这种动态表单中的基本黑客是发布的表单数据应该与属性名称匹配。

Ex:动态控件数组的最终属性名称应为。      ApplicationParameters [0] .Name和ApplicationParameters [0] .Keep 和
     ApplicationParameters [1] .Name和ApplicationParameters [1] .Keep      .....

要实现这一点,请仅使用松散耦合的帮助程序Html.TextBox()。

答案 1 :(得分:0)

在有用的答案之后,我能够按照我想要的方式工作。我所做的是服务器和客户端代码的组合,其基本思想是在ViewModel中添加一个额外的属性,我将其命名为ControlName,类型为string。有一点很棒的是,如果你的ViewModel发生了变化,你就可以轻松地将代码调整到当前的需求而不会有太多的麻烦,更不用说你可以通过向每个ViewModel子级添加ControlName属性轻松地进入多个深度级别。 / p>

注意:以下示例不是OP中提到的那个

首先,你需要某种包装器(在我的例子中是一个表)和一个允许你创建新的控件行的链接:

        @Html.ActionLink("Add attribute", "AddProductCategoryAttribute", null, new { id = "addProductCategoryAttribute" })
        <table class="table table-condensed table-striped">
            <thead>
                <tr>
                    <th>

                    </th>
                    <th>
                        Attribute
                    </th>
                    <th>
                        Measure
                    </th>
                </tr>
            </thead>
            <tbody id="productCategoryAttributes"></tbody>
        </table>

在客户端,你需要这样的东西

    <script type="text/javascript">
    $("#addProductCategoryAttribute").click(function () {
        elementCount = $(".productCategoryAttribute").length;

        $.ajax({
            url: this.href + "?elementCount=" + elementCount,
            cache: false,
            success: function (html) {
                $("#productCategoryAttributes").append(html);
            }
        });
        return false;
    })
</script>

请注意附加的 elementCount 到链接 - 此查询字符串用于让Action方法知道已存在多少元素。在谈论Action方法时,现在就是它的样子。

    public ActionResult AddProductCategoryAttribute(int elementCount)
    {
        ProductCategoryOverview.ProductCategoryAttributeVM productCategoryAttributeVM = new ProductCategoryOverview.ProductCategoryAttributeVM();
        productCategoryAttributeVM.ControlName = "ChangeThisNameToWhateverIsNeeded[" + elementCount.ToString() + "].";
        productCategoryAttributeVM.Keep = true;

        return View(productCategoryAttributeVM);
    }