MVC Kendo Grid使用MultiSelect自定义弹出编辑器 - 无法在模型中获取所选项目

时间:2016-05-19 21:50:49

标签: asp.net-mvc-4 kendo-asp.net-mvc multi-select

标题说明了一切。

POPUP FORM:

@using Kendo.Mvc.UI
@using Batc.AgileApp.Web.Areas.ProductReuse.Models
@model BomViewModel

@Html.HiddenFor(m => m.BomId)
@Html.HiddenFor(m => m.Row)
@Html.HiddenFor(m => m.UserWorkSessionId)


<div class="container-fluid">
    <div class="form-group row">
        <div class="col-xs-4 col-sm-4">
            <span>
                @Html.LabelFor(model => model.ProductClass)
            </span>
            <br/>@(Html.Kendo().DropDownListFor(m => m.ProductClass)
                       .DataTextField("Text")
                       .DataValueField("Value")
                       .HtmlAttributes(new {style = "width:125px"})
                       .DataSource(source =>
                       {
                           source.Read(read => { read.Action("GetDropDownLookups", "AjaxProductReuse", new {id = "ProductClass"}); });
                       })
                       )
            <div style="font-weight: normal;">
                @Html.ValidationMessageFor(model => model.ProductClass)
            </div>
        </div>
        <div class="col-xs-4 col-sm-4">
            <span>
                @Html.LabelFor(model => model.ProgramSelectedList)
            </span>

            @(Html.Kendo().MultiSelectFor(m => m.ProgramSelectedList)
                  .Placeholder("Select program...")
                  .HtmlAttributes(new {style = "width:200px"})
                  .DataSource(source =>
                  {
                      source.Read(read => { read.Action("GetLookups", "AjaxProductReuse", new {id = "Program"}); });
                  })
                  )
            <div style="font-weight: normal;">
                @Html.ValidationMessageFor(model => model.ProgramSelectedList)
            </div>
        </div>
    </div>
</div>

GRID FORM(cshtml视图):

@using Batc.AgileApp.Web.Areas.ProductReuse.Models
@using Kendo.Mvc.UI
@model AssemblyViewModel


@using (Html.BeginForm("Assembly", "ProductReuse", FormMethod.Post, new {id = "frmStartScreen"}))
{
    @Html.HiddenFor(m => m.Status)
    @Html.HiddenFor(m => m.UserWorkSessionId)
    @Html.HiddenFor(m => m.GlobalPartNum)

    @(Html.Kendo().Grid<BomViewModel>()
          .Name("bom-prGrid-kendoGrid")
          .HtmlAttributes(new {@class = "prGrid"})
          .ClientRowTemplate("")
          .Columns(columns =>
          {
              columns.Command(cmd => cmd.Edit()).Width(80);
              columns.Bound(g => g.BomId).Hidden();
              columns.Bound(g => g.IsEditable).Hidden();
              columns.Bound(g => g.Row).Width(75).Title("Row");
              columns.Bound(p => p.Program).Width(100).Title("Program");
              columns.Bound(p => p.ProductClass).Width(100).Title("Product<br/>Class");
              columns.Bound(p => p.ResponsibleEng).Width(120).Title("Resp Eng");
              columns.Bound(p => p.ProjectNum).Width(100).Title("Project<br/>No");
              columns.Bound(p => p.AccessControl).Width(150).Title("Access Control");
          })
          .DataSource(dataSource => dataSource
              .Ajax()
              .Model(model => { model.Id(g => g.BomId); })
              .PageSize(100)
              .Read(r => r.Action("GetCloneAssembly", "AjaxProductReuse").Data("ProductReuseGridReadData"))
              .Update(u => u.Action("UpdateBomItem", "AjaxProductReuse").Type(HttpVerbs.Post))
              .Events(e => e.Error("ajax_error").Sync("dataSource_sync").Change("dataSource_change"))
          )
          .Events(e => e.DataBound("onDataBound").Edit("onEdit"))
          .Pageable(pager => pager
              .Input(true)
              .Numeric(true)
              .Info(true)
              .PreviousNext(true)
              .Refresh(true)
              .PageSizes(new int[] {100, 250, 500, 1000})
          )
          .Sortable()
          .Scrollable()
          .Filterable()
          .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("BOMForm").Window(w => w.Title("Manage BOM Item").Name("BOMForm"))) 
          .Resizable(resizing => resizing.Columns(true)).Reorderable(reorder => reorder.Columns(true))
          )
}

模型(感兴趣的属性):

[MetadataType(typeof(BomViewModelMetaData))]
public class BomViewModel: BomModel
{
    public int BomId { get; set; }
    public int Row { get; set; }
    public int UserWorkSessionId { get; set; }
    public string ProductClass { get; set; }
    public string Program { get; set; }
    public List<string> ProgramSelectedList { get { return Program.ToList(); } set { Program = value.ToDelimitedString(); } }

}

我的(ajax)控制器看起来像:

public JsonResult UpdateBomItem([DataSourceRequest] DataSourceRequest request, BomViewModel bomViewModel)   // [Bind(Prefix = "models")]
{
    var command = _mapper.Map<BomModel>(bomViewModel);
    var commandResponse = _productReuseService.UpdateBomItem(command);
    var response = _mapper.Map<List<BomViewModel>>(commandResponse);
    return Json(ToDataSourceResult(response, request, modelState: ModelState));
}

我遇到的问题是发布到我的控制器的数据。在fiddler中看起来像这样(前3个项目映射到控制器中的第一个对象,其余为模型):

sort=
&group=
&filter=
&Program=PROGRAM_ORIGINAL
&ProgramSelectedList[0]=PROGRAM_01
&ProgramSelectedList[1]=PROGRAM_02
&UserWorkSessionId=45
&Row=10
&ProductClass=1
&BomId=151927

我的期望是:

sort=
&group=
&filter=
&Program=PROGRAM_01, PROGRAM_02
&ProgramSelectedList=PROGRAM_01
&ProgramSelectedList=PROGRAM_02
&UserWorkSessionId=45
&Row=10
&ProductClass=1
&BomId=151927

是否有&#34;特殊&#34;设置在Kendo或JQuery或.NET中以使此列表正常运行?我目前只在MVC HTML Helper模式下使用Kendo。这意味着我几乎没有JS在UI方面支持我想要的操作。

这是一个内部LOB应用,使用率低,用户最少。

1 个答案:

答案 0 :(得分:0)

经过多次挖掘和挫折后,答案非常简单。我需要添加一个JS帮助器来将数据放入MVC Model Binder可以理解的格式中。

<script>
    function getUpdatedBomRowData() {
        var program = $("#ProgramSelectedList").data("kendoMultiSelect").value().toString();
        return {
            program: program
        }
    }
</script>

然后在网格的数据源更新操作中,我添加了一个Data(...)方法:

.DataSource(dataSource => dataSource
    .Ajax()
    .Model(model => { model.Id(g => g.BomId); })
    .PageSize(100)
    .Read(r => r.Action("GetCloneAssembly", "AjaxProductReuse").Data("ProductReuseGridReadData"))
    .Update(u => u.Action("UpdateBomItem", "AjaxProductReuse").Type(HttpVerbs.Post).Data("getUpdatedBomRowData"))
    .Events(e => e.Error("ajax_error").Sync("dataSource_sync").Change("dataSource_change"))
)

然后,JS会在发送到控制器之前将逗号分隔的字符串放入Program属性中。由于程序被用作(A)表字段的DB表示,以及(B)List ProgramSelectedList的支持字段,我的代码现在似乎很高兴。