【问题标题】:How to update Kendo Grid row from window如何从窗口更新 Kendo Grid 行
【发布时间】:2015-04-21 13:13:52
【问题描述】:

设置:

  • ASP MVC 项目
  • Razor 视图中的剑道网格
  • 列自定义命令,调用...
  • JavaScript 使用 refresh() URL 打开 Kendo 窗口以自定义表单的部分视图
  • 表单有一个输入 type=button 调用 JavaScript

障碍:

如何使用新模型(来自窗口/表单 javascript)更新 Grid 的行(dataItem?)。我无法获得目标数据项的句柄。 Select() 在此处不适用,因为未选择该行。相反,自定义按钮事件会打开模态网格窗口,其中包含更新、关闭等字段和命令。

我可以使用 Grid 的本机编辑,但我想要完成的是一种完全自定义弹出窗口的方法,该窗口显示可用于呈现 CRUD 操作的部分视图。

顺便说一句:这样做的理由是优化网格行中的空间,这些空间通常会被用于编辑和删除的不必要按钮所消耗,这些按钮是通过使用 Kendo 本机控件属性放置的。在我的例子中,我觉得这更好地呈现在一个单独的细节视图中,比如模型网格窗口。

同样,不使用 Select(),我无法理解如何在 Window/form JavaScript 中获取调用它的 Grid 行的句柄,以便使用新模型数据更新该行。

感谢您的宝贵时间。

【问题讨论】:

  • 仅供参考,虽然鼓励为您的问题添加答案,但将您的答案编辑到您的问题中是不合适的。

标签: kendo-ui window command kendo-grid


【解决方案1】:

使用您的方法,您正在执行双重请求,所以我的建议是: 在编辑时打开一个通过 MVVM 绑定到行的窗口:

function edit(e) {
    //get the row which belongs to clicked edit button
    var item = this.dataItem($(e.currentTarget).closest("tr"));

    //bind the window to the item via mvvm http://docs.telerik.com/kendo-ui/framework/mvvm/overview 
    kendo.bind($("#window"), item);
}

窗口包含一个编辑器模板(Shared/EditorTemplates/Client.cshtml):

@(Html.Kendo().Window().Name("window")
    .Title("Client Details")
    .Visible(false)
    .Modal(true)
    .Draggable(true)
    .Width(400)
    .Content(@<text>
        @Html.Partial("EditorTemplates/Client", new Product())
    </text>))

//Put in every element in the window data-bind="value:INPUT NAME" 
//<input name="price" /> become <input name="price" data-bind="value: price" />
$("#window [name]").each(function () {
     var name = $(this).attr("name")
     $(this).attr("data-bind", "value:" + name );
 });

编辑器模板:

@model Product
@Html.TextBoxFor(m => m.Name)

【讨论】:

  • 谢谢塔瑞克。 2 件事:1)您能否具体评论一下 2 个请求点和任何成本(即性能等),以及 2)请在“编辑”功能中添加一些 cmets,以便我可以消化它。我对javascript有点陌生。谢谢!
  • 1) 2 个请求是:第一个页面加载包含网格,第二个是在 iframe 窗口(剑道窗口)“/Clients/Edit”中打开的编辑页面,所以你正在访问服务器两次
  • Tarek Najem 是的!我现在明白了。第一个是第一个是必要的,但第二个命中是可以避免的,正如我相信你在上面指出的那样。第二个是我尝试在弹出窗口中将模型数据放入该部分视图中。我会审核您的建议并重新考虑。
  • 顺便说一句:更多的发现让我意识到可以有相当多的 javascript 来管理客户端控制事件和状态。为了找到一种管理客户端工作的方法,我偶然发现了 Knockout.js。使用它和映射,我认为现在管理客户端工作会更容易。最初,我忽略了您的引用“数据绑定”和 MVVM,但又回到了原点。诡异的。我没有使用 Knockout,但看起来是个好主意...
  • @[Tarek Najem] 问题?关于“窗口”,我使用的是剑道窗口(参见“答案”代码),我无法找到在该窗口中调用 Partial 而不调用 Refresh 的方法。所以如果你有办法,请告诉我。谢谢。
【解决方案2】:

此演示展示了如何获取绑定到按下自定义命令键的列的数据项的引用,并在窗口中显示相应的信息。您也可以使用 dataItem 来更新 Grid:

http://demos.telerik.com/kendo-ui/grid/custom-command

这也是一个例子:

http://dojo.telerik.com/abUHI 看看showDetails函数

【讨论】:

  • 谢谢@knikolov。我找到了很多例子来展示如何在基本意义上使用网格。然而,正如我上面所说,我的目标是拥有自定义命令来呈现模型对话,该对话将用于更新网格。从那以后,我发现了我需要的东西,并用我的发现更新了我的问题。很明显,我还没有掌握服务器与客户端目标的概念,如我上面的发现所示。似乎有很多编码,所以我对简化方法的想法持开放态度。任何人? (谢谢!)
  • 更正:“模型对话”应阅读“模态对话”。哎呀!
【解决方案3】:

我发布此消息后的发现...

我是 Web 演示开发的新手,因此掌握客户端与服务器端元素的区别及其范围是关键。同样,学习剑道网格的各种细节也很有帮助。

继续我目前的解决方案...

获取从自定义命令事件中选择的行项的句柄未使用 Select() 完成,因为未选择行。正如之前在其他帖子中所述,这只是所需工作的一部分。在自定义命令事件处理程序 JavaScript 中(在下面的完整解决方案中再次看到):

var detailDataItem = this.dataItem($(e.target).closest("tr"));

我的解决方案:

在托管 Kendo Grid 的父窗口中:

@* Declare modal Kendo Grid window control *@

@helper ClientGrid()
{
    @(Html.Kendo().Grid<Purevision.Models.Person>()
          .Name("grid")
          .Columns(columns =>
          {
              columns.Bound(c => c.FirstName).Width(100);
              columns.Bound(c => c.LastName).Width(130);
              columns.Bound(c => c.Email).Width(140);
              columns.Bound(c => c.Phone).ClientTemplate("#= (data.Phone) ? formatPhoneNumber(data.Phone) : 'none' #").Width(130);
              columns.Bound(c => c.Comments).Hidden().Width(140);
              columns.Bound(c => c.UserId).Hidden();
              columns.Bound(c => c.Id).Hidden();
              columns.Command(command =>
              {
                  command.Custom("Archive").Click("archiveCommand");
                  command.Custom("Detail").Click("detailCommand");
              }).Width(90);
          })
          .ToolBar(toolbar => toolbar.Create())
          .Selectable(s => s.Mode(GridSelectionMode.Single))
          .Events(e => e.Change("onChange").DataBound("onDataBound").DataBinding("onDataBinding"))
          .Scrollable()
          .Sortable()
          .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("Edit"))
          .Pageable(pageable => pageable
              .Refresh(true)
              .PageSizes(true)
              .ButtonCount(5))
          .DataSource(dataSource => dataSource
              .Ajax()
              .PageSize(20)
              .Events(events => events.Error("error_handler"))
              .Model(model => model.Id(c => c.Id))
              .Create(create => create.Action("People_Create", "Clients"))
              .Read(read => read.Action("People_Read", "Clients"))
              .Update(update => update.Action("People_Update", "Clients"))
              .Destroy(update => update.Action("People_Destroy", "Clients"))
              )
        )
}

@* Declare modal Kendo Grid window control;  MUST be named 'detailWindow' as referenced by partial view script *@

@(Html.Kendo().Window().Name("detailWindow")
    .Title("Client Details")
    .Visible(false)
    .Modal(true)
    .Draggable(true)
    .Width(400)
    .Content(@<text>
        @Html.Partial("_edit", new Person())
        </text>
    )

<script type="text/javascript">

    function detailCommand(e) {
        var window = $("#detailWindow");
        var kWnd = window.data("kendoWindow");
        var data = this.dataItem($(e.target).closest("tr"));

        e.preventDefault();

        kendo.bind(window, data);
        kWnd.center().open();
    }
</script>

在 Kendo 模态窗口中呈现的局部视图 _edit.cshtml:

<div class="form-group">
    @Html.LabelFor(model => model.FirstName, htmlAttributes: new { @class = "control-label col-md-3" })
    <div class="col-md-4">
        @Html.EditorFor(model => model.FirstName)
        @Html.ValidationMessageFor(model => model.FirstName)
    </div>
</div>

<input type="button" id="updateButton" value="Update2" class="btn btn-default" />

在表单准备就绪期间连接按钮事件,该事件获取仍在客户端范围内的网格控件的句柄:

<script type="text/javascript">

    // as mentioned by Tarek, bind each control's value attribute

    $("#detailWindow [name]").each(function () {
        var name = $(this).attr("name");
        $(this).attr("data-bind", "value:" + name );
    });

    $(document).ready(function (e) {
        var window = $("#detailWindow");
        var grid = $("#grid").data("kendoGrid");

        $("#updateButton").click(function (e) {
            grid.saveChanges();
            window.data("kendoWindow").close();
        });
    });
</script>

我愿意在这里提出重构建议。似乎有很多 JavaScript 客户端编码来完成针对 Kendo Grid 的自定义活动。 (叹气)不过,我很高兴拥有多功能性。 (微笑)

为了希望得到这个有用的答案,需要进行大量的重新编辑。让我知道。 ;)

参考: Telerik Forums / Kendo UI Forum / Grid / How does Grid update its dataSource?

【讨论】:

  • 只是好奇,因为这个答案是如此彻底。你有: .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("Edit")) 但我看不到任何地方显示名为“Edit”的模板。我看到名为“_edit.cshtml”的局部视图,Kendo 是否忽略了下划线和大写?
  • @RyanHoyle,我也这么想。它几乎看起来像代码中的死胡同,或者可能是从演示中复制的代码作为起点。使用自定义命令,将永远不会调用该弹出窗口。此外(除非发现约定比我理解的更多)它将从Views\Shared\EditorTemplates 中名为Edit.cshtml 的部分视图中提取,OP 没有提及。我确信如果没有该模板引用,这将起作用,但我也想知道它是否可以在删除整个流畅的.Editable(...) 配置的情况下工作。考克斯先生?
猜你喜欢
  • 2015-10-27
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
  • 2014-02-26
相关资源
最近更新 更多