使用IEnumerable Model属性进行Kendo内联编辑

时间:2014-08-25 07:01:30

标签: c# asp.net-mvc kendo-ui kendo-grid kendo-asp.net-mvc

如果有人可以提供以下建议,我会很感激:

我有一个包含另一个模型集合的模型:

public class ContractModel
{
    public ContractModel()
    {
          this.ContractCurrencyClauses = new HashSet<ContractCurrencyClause>();
    }
    public System.Guid ID { get; set; }

    public virtual ICollection<ContractCurrencyClause> ContractCurrencyClauses { get; set; }

   //other model properties
}

public partial class ContractCurrencyClause
{
    public System.Guid ID {get; set;} //PK
    public System.Guid CONTRACT_ID { get; set; } //FK on ContractModel(ID)
    public string CURRENCY { get; set; } 
    public Nullable<decimal> RATE { get; set; }
}

问题是我不确定在创建ContractCurrencyClauses时如何临时存储ContractModel的集合。 我将ContractModel

的新实例传递给我
    [HttpGet]
    public ActionResult Create()
    {
        ContractModel Contract = context.Contracts.Create();
        Contract.ID = Guid.NewGuid();
        return PartialView(Contract);
    }

在我看来:

@model ContractModel
@using (Ajax.BeginForm("Create", null, new AjaxOptions() { ... }))
{
@Html.HiddenFor(model=>model.ID)

@(Html.Kendo().Grid(Model.ContractCurrencyClauses)
               .Name("ContractCurrencyClauses")
               .ToolBar(toolbar => toolbar.Create())
               .Columns(columns => {
                        columns.Bound(u => u.ID).Hidden(true);
                        columns.Bound(u => u.CONTRACT_ID).Hidden(true);
                        columns.Bound(u => u.CURRENCY);
                        columns.Bound(u => u.RATE);
                        columns.Command(command => { command.Edit(); command.Destroy(); });
                        })

                        .Editable(editable => editable.Mode(GridEditMode.InLine))
                        .DataSource(dataSource => 
                                dataSource.Ajax()
                                .Model(model =>
                                {
                                    model.Id(u => u.ID);                                        
                                    model.Field(u => u.CONTRACT_ID).DefaultValue(Model.ID);
                                    model.Field(u => u.ID).DefaultValue(Guid.NewGuid());
                                })
                         .Create(create => create.Action("CreateCurClause", "Contracts"))
                         .Update(update => update.Action("UpdateCurClause", "Contracts"))
                         .Destroy(destroy => destroy.Action("DestroyCurClause", "Contracts")))
                )
 }

我提交新网格条目时的第一个问题,我收到了null模型的ContractCurrencyClause

 public ActionResult CreateCurClause([DataSourceRequest]DataSourceRequest request, ContractCurrencyClause clause)
    {
        if(ModelState.IsValid)
        {

        }
        return Json(new[] { clause }.ToDataSourceResult(request, ModelState));
    }

我想这是因为当我按下网格工具栏中的Add按钮时,没有创建模型的新实例,因为我看到了JS错误:无法读取{{1}的属性ID }}

其次,我不知道如何暂时绑定和存储null,以便在用户提交主表单时传递整个集合。

非常感谢。

2 个答案:

答案 0 :(得分:1)

编辑2:

ContractsController

 public class ContractsController : Controller
    {
        //
        // Static variables for Demo only
        static ContractModel model;
        static ICollection<ContractCurrencyClause> tmpContractCurrencyClauses { get; set; }

        public ActionResult Index()
        {
            if (model == null)
            {
             model = new ContractModel();
             tmpContractCurrencyClauses = new HashSet<ContractCurrencyClause>();
             model.ContractCurrencyClauses = tmpContractCurrencyClauses;
            }
            model.ContractCurrencyClauses = tmpContractCurrencyClauses;
            return View(model);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(ContractCurrencyClause contract)
        {
            contract.CONTRACT_ID = new Guid();
            tmpContractCurrencyClauses.Add(contract);
            RouteValueDictionary routeValues = this.GridRouteValues();

            return RedirectToAction("Index", routeValues);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Update(ContractCurrencyClause contract)
        {
            tmpContractCurrencyClauses.Add(contract);
            RouteValueDictionary routeValues = this.GridRouteValues();

            return RedirectToAction("Index", routeValues);
        }
    }

Index.cshtml

@Html.HiddenFor(model=>model.ID)
@(Html.Kendo().Grid(Model.ContractCurrencyClauses)
               .Name("ContractCurrencyClauses")
               .ToolBar(toolbar => toolbar.Create())
               .Columns(columns => {
                        columns.Bound(u => u.CONTRACT_ID).Hidden(true);
                        columns.Bound(u => u.CURRENCY);
                        columns.Bound(u => u.RATE);
                        columns.Command(command => { command.Edit(); command.Destroy(); });
                        })

                        .Editable(editable => editable.Mode(GridEditMode.InLine))
                        .DataSource(dataSource => 
                                dataSource.Ajax()
                                .Model(model =>
                                {
                                    model.Id(u => u.CONTRACT_ID);
                                    //model.Id(u => u.CURRENCY);  Kendo datasource does not support composite data keys.  
                                     model.Field(u => u.CONTRACT_ID).DefaultValue(Model.ID);
                                })
                         .Create(create => create.Action("Create", "Contracts"))
                         .Update(update => update.Action("Update", "Contracts"))
                         .Destroy(destroy => destroy.Action("DestroyCurClause", "Contracts")))
                )

编辑1:

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Create(ContractCurrencyClause contract)
    {
     ...
    }

您是否尝试过将kendo网格放在表单之外?

根据Kendo文档

  

Kendo UI MVC Grid在服务器内部使用表单元素   编辑已启用。这意味着小部件不能放在另一个小部件中   页面上的表单元素,因为嵌套表单不是   符合标准的。

还使用kendo doc验证创建,更新方法签名。

如果您需要立即发送所有数据,您可以像这样序列化网格

var form data = JSON.stringify(dataSource.data());

答案 1 :(得分:0)

我终于找到了更好的解决方案,我使用InCell编辑:

  @(Html.Kendo().Grid(Model.ContractCurrencyClauses)
                          .Name("ContractCurrencyClauses")
                          .ToolBar(toolbar => { toolbar.Create(); })
                          .Columns(columns => {
                              columns.Bound(p => p.CONTRACT_ID).Hidden().ClientTemplate("#= CONTRACT_ID #" +
                                "<input type='hidden' name='ContractCurrencyClauses[#= index(data)#].CONTRACT_ID' value='#= CONTRACT_ID #' />"
                              );                                  
                              columns.Bound(p => p.CURRENCY).ClientTemplate("#= CURRENCY #" +
                               "<input type='hidden' name='ContractCurrencyClauses[#= index(data)#].CURRENCY' value='#= CURRENCY #' />"
                              ).EditorTemplateName("CurrencyDDL");

                              columns.Bound(p => p.RATE).ClientTemplate("#= RATE #" +
                               "<input type='hidden' name='ContractCurrencyClauses[#= index(data)#].RATE' value='#= RATE #' />"
                              );

                              columns.Command(command => { command.Destroy(); });
                          })
                        .Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
                        .DataSource(dataSource => 
                            dataSource.Ajax()
                            .Model(model =>
                            {
                                model.Id(u => u.CONTRACT_ID);
                                model.Field(u => u.CONTRACT_ID).DefaultValue(Model.ID);                                   
                            })
                            .ServerOperation(false)
                            )
            )

<script>
    function index(dataItem) {
        var data = $("#ContractCurrencyClauses").data("kendoGrid").dataSource.data();
        return data.indexOf(dataItem);
    }
</script>

网格在我的主窗体中,当我对它进行求和时,我会在控制器中收到ContractCurrencyClauses的完整列表。

Simillar解决方案:Project