将动态和嵌套数组的更改从视图发布到控制器

时间:2016-02-23 17:39:19

标签: javascript c# html asp.net-mvc razor

我正在开发一个MVC页面,该页面应该呈现基于XML文件的表单。

XML是类型'设置'的序列化类对象。它可以包含布尔,字符串和整数数组 - 以及同一个类的零个或多个相同子元素的数组(元素的递归嵌套以反映XML的灵活结构)。

这应该是某些配置XML文件的通用解决方案。

MVC页面应该显示表单,允许编辑它并保存设置 - 将类序列化回配置XML文件。这样就行了,即我可以编辑数据并保存。

它还应该允许动态添加元素(道歉,布局是一个非常初始的版本,它不显示元素的嵌套Root => Config(s)=> Stage(s)=>语言(一个或多个)。

enter image description here

现在,从视觉角度将项目添加到表单中可以正常工作,但是当发布表单时,SubElements数组不包含新项目。

现在让我给你看一些代码:

 public class ConfigModel : IPluginConfiguration
{
    public ConfigModel()
    {
    }

    public StringPluginSetting[] StringSettings { get; set; }
    public BooleanPluginSetting[] BooleanSettings { get; set; }
    public IntegerPluginSetting[] IntegerSettings { get; set; }
    public PickListPluginSetting[] PickListSettings { get; set; }
    public PluginConfigElement[] SubElements { get; set; }
    public int PluginFrequencyMinutes { get; set; }
    public bool IsDeactivated { get; set; }
    public bool IsTemplate { get; set; }

    }

主视图

@model TestAppForConfigHelpers.Models.ConfigModel
@if (Model != null)
{
using (Html.BeginForm())
{

        @Html.Partial("_GlobalSettings")
        <br/>
        <br/>

        for (int i = 0; i < Model.SubElements.Length; i++)
        {
            <br/>
            <p>Config @i</p>
            <br/>
            @Html.EditorFor(m => Model.SubElements[i])
        }
        <br/>
        <input type="submit" value="Save configuration"/>
    } 
}

编辑模板:

@model ConfigHelperTest.ConfigurationHelper.PluginConfigElement

<div>
<table id="parentTable_@Model.GetHashCode()" class="table-bordered" style="margin-left: @string.Format(HomeController.Margin+"px")">
    <tr  class="label-primary">
        <td colspan="99"><input type="button" class="btn-xs" value="Add" id="@string.Format("addNewElement" + Model.GetHashCode())" />@Model.ElementType</td>
    </tr>
    <tr>
        <td>
            @Html.HiddenFor(model => model.ElementType)
            @Html.EditorFor(model => model.StringSettings)
        </td>
    </tr>
</table>

@if (Model.SubElements != null)
{
    for (int i = 0; i < Model.SubElements.Length; i++)
    {
        @Html.EditorFor(m => Model.SubElements[i])
    }
}
</div>

添加元素的Javascript:

<script type="text/javascript">
$(document).ready(function() {
    $('#addNewElement'+@Model.GetHashCode()).on('click', function() {
    var modelDataJson = '@Html.Raw(Json.Encode(Model))';
    $.ajax({
        url: '@(Url.Action("AddNewElement", "Home"))',
        type: 'post',
        data:  { elementInJson: modelDataJson},
        success: function(partialView) {
            var id = 'parentTable_' + @Model.GetHashCode();
            $('#'+id).parent().parent().append(partialView);

        }
    });
});
});
</script>

JavaScript调用的控制器操作

public ActionResult AddNewElement(string elementInJson)
        {
            PluginConfigElement element =
                new JavaScriptSerializer().Deserialize<PluginConfigElement>(elementInJson);
            //simply add a new one based on the source one, with all subelements etc
            return PartialView("~/Views/Shared/EditorTemplates/PluginConfigElement.cshtml", element);
        }

任何帮助表示赞赏!

干杯

更新代码
根据Stephen的建议,我稍微更新了代码 - 删除了不需要的控制器操作,停止使用循环编辑器模板并更改了点击事件上的javascript被触发的方式。

主要观点:

@if (Model != null)
{
    using (Html.BeginForm())
    {
        <div id="formDiv">

            @Html.Partial("_GlobalSettings")
            <br/>
            <br/>

            @Html.EditorFor(m => Model.SubElements)

            <br/>
            <input type="submit" value="Save configuration"/>
        </div>
    }
}

编辑模板+ javascript:

@model ConfigHelperTest.ConfigurationHelper.PluginConfigElement
<div>
<table  class="table-bordered" >
    <tr  class="label-primary">
        <td colspan="99"><input type="button" class="btn-xs addNewElement" value="Add" onclick="addNewElement(this)" />@Model.ElementType</td>
    </tr>
    <tr>
        <td>
            @Html.HiddenFor(model => model.ElementType)
            @Html.EditorFor(model => model.StringSettings) //custom editor template below
            //@Html.EditorFor(model => model.BooleanSettings) not used now for simplicity
        </td>
    </tr>
</table>

@if (Model.SubElements != null)
{
    @Html.EditorFor(m => Model.SubElements)
}
</div>

<script type="text/javascript">
    function addNewElement(element) {
        //todo
}
</script>

现在,我想使用建议的in this answer方法,但我不知道应该在哪里放置隐藏的模板div - 更重要的是,如果我已经存在,那么这个隐藏的div应该包含什么使用编辑器模板来设置可能的设置对象(字符串,整数,布尔值)......

<div id="NewSubElement" style="display: none">

</div>

设置数组的编辑器模板

@model ConfigHelperTest.ConfigurationHelper.PluginSetting

@if (Model != null)
{
        <tr>
            <td><b>
                    @Html.HiddenFor(m => m.Name)
                    @Html.DisplayFor(m => m.Name)
                </b>
            </td>
            <td>
                @Html.EditorFor(m => m.Value)
                @Html.HiddenFor(m => m.IsOptional)
            </td>
        </tr>
}

0 个答案:

没有答案