Kendo UI Grid Master 和 Detail 按钮错误

Posted

技术标签:

【中文标题】Kendo UI Grid Master 和 Detail 按钮错误【英文标题】:KendoUI Grid Master And Detail Buttons Bug 【发布时间】:2015-08-09 17:12:41 【问题描述】:

如果您对主行按钮和详细信息行按钮使用相同的名称,您会收到这些按钮的双击事件。我认为 kendo ui 使用“k-grid-Your Button Name”类属性绑定事件。不要在主行和详细行中使用相同的按钮名称。

name: btnName,
template: '<a class="k-button k-button-icontext k-grid-' + btnName +'" ><span class="k-icon k-i-refresh"></span></a>',
click: function (e) 

【问题讨论】:

这不是错误。你没有正确使用它。 我对所有删除操作都使用了确认方法。如果你想使用相同的方法,你可以看到这个错误。 请提供一个说明错误的工作示例。 Brett,我针对这种情况发布了一个示例。 【参考方案1】:

Grid 将带有 k-grid-xxx 类的按钮解释为内置命令,这些命令确实应该具有唯一的名称。如果不希望这样做,您可以设置不以 k-grid 模式开头的 CSS 类,并通过 jQuery 手动附加点击处理程序。

【讨论】:

【参考方案2】:
I create two button functions for delete operation. 

第一个函数名称是“deleteButton()”,它总是返回同名的“删除”按钮。

第二个函数名称是“deleteButton2()”,由于“prmName”参数,它可以返回不同的名称按钮。

请在详细网格中的两个按钮的确认消息中检查产品名称。我们将看到不同的消息。

因为同名按钮会触发主按钮和详细信息的两个点击事件。 你可以在调试中看到它。

因此,我们不会为细节和主网格按钮使用相同的名称。

var sampleData = [
  ProductID: 1,
  ProductName: "Apple iPhone 5s",
  Introduced: new Date(2013, 8, 10),
  UnitPrice: 525,
  Discontinued: false,
  UnitsInStock: 10
, 
  ProductID: 2,
  ProductName: "HTC One M8",
  Introduced: new Date(2014, 2, 25),
  UnitPrice: 425,
  Discontinued: false,
  UnitsInStock: 3
, 
  ProductID: 3,
  ProductName: "Nokia 5880",
  Introduced: new Date(2008, 10, 2),
  UnitPrice: 275,
  Discontinued: true,
  UnitsInStock: 0
];

function dataSource() 

  return new kendo.data.DataSource(
    transport: 
      read: function(e) 
        e.success(sampleData);
      ,
      create: function(e) 
        e.data.ProductID = nextId(sampleData);
        sampleData.push(e.data);
        e.success(e.data);
      ,
      update: function(e) 
        sampleData[getIndexById(sampleData, e.data.ProductID)] = e.data;
        e.success();
      ,
      destroy: function(e) 
        sampleData.splice(getIndexById(sampleData, e.data.ProductID), 1);
        e.success();
      
    ,
    error: function(e) 
      alert("Status: " + e.status + "; Error message: " + e.errorThrown);
    ,
    pageSize: 10,
    batch: false,
    schema: 
      model: 
        id: "ProductID",
        fields: 
          ProductID: 
            editable: false,
            nullable: true
          ,
          ProductName: 
            validation: 
              required: true
            
          ,
          Introduced: 
            type: "date"
          ,
          UnitPrice: 
            type: "number",
            validation: 
              required: true,
              min: 1
            
          ,
          Discontinued: 
            type: "boolean"
          ,
          UnitsInStock: 
            type: "number",
            validation: 
              min: 0,
              required: true
            
          
        
      
    
  );

;

var sampleDetailData = [
  ProductID: 11,
  ProductName: "Detail Product 1"
, 
  ProductID: 12,
  ProductName: "Detail Product 2"
, 
  ProductID: 13,
  ProductName: "Detail Product 3"
];

function detailDataSource() 

  return new kendo.data.DataSource(
    transport: 
      read: function(e) 
        e.success(sampleDetailData);
      ,
      create: function(e) 
        e.data.ProductID = nextId(sampleDetailData);
        sampleDetailData.push(e.data);
        e.success(e.data);
      ,
      update: function(e) 
        sampleDetailData[getIndexById(sampleDetailData, e.data.ProductID)] = e.data;
        e.success();
      ,
      destroy: function(e) 
        sampleDetailData.splice(getIndexById(sampleDetailData, e.data.ProductID), 1);
        e.success();
      
    ,
    error: function(e) 
      alert("Status: " + e.status + "; Error message: " + e.errorThrown);
    ,
    pageSize: 10,
    batch: false,
    schema: 
      model: 
        id: "ProductID",
        fields: 
          ProductID: 
            editable: false,
            nullable: true
          ,
          ProductName: 
            validation: 
              required: true
            
          
        
      
    
  );

;

function detailInit(e) 
  var detailRow = e.detailRow;
  detailRow.find("#detailGrid").kendoGrid(
    dataSource: detailDataSource(),
    pageable: true,
    toolbar: ["create"],
    columns: [
      field: "ProductName",
      title: "Mobile Phone"
    , 
      command: ["edit", deleteButton(),deleteButton2("DetailDelete")],
      title: "&nbsp;",
      width: "200px"
    ],
    editable: 
      mode: "popup",
      confirmation: false
    
  );
;

function nextId(prmData) 
  return prmData.length + 1;
;

function getIndexById(prmData, id) 
  var idx,
    l = prmData.length;

  for (var j; j < l; j++) 
    if (prmData[j].ProductID == id) 
      return j;
    
  
  return null;


var windowTemplate = kendo.template($("#windowTemplate").html());

var dWindow = $("#window").kendoWindow(
  title: "Are you sure you want to delete this record?",
  visible: false,
  width: "400px",
  height: "200px",
).data("kendoWindow");

var deleteButton = function() 
  return 
    name: "Delete",
    click: function(e) 
      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() 
        grid.removeRow(row);
        dWindow.close();
      )
      $("#noButton").click(function() 
        dWindow.close();
      )
    
  
;

var deleteButton2 = function(prmName) 
  return 
    name: prmName,
    click: function(e) 
      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() 
        grid.removeRow(row);
        dWindow.close();
      )
      $("#noButton").click(function() 
        dWindow.close();
      )
    
  
;

$("#grid").kendoGrid(
  dataSource: dataSource(),
  pageable: true,
  toolbar: ["create"],
  columns: [
    field: "ProductName",
    title: "Mobile Phone"
  , 
    field: "Introduced",
    title: "Introduced",
    format: "0:yyyy/MM/dd",
    width: "200px"
  , 
    field: "UnitPrice",
    title: "Price",
    format: "0:c",
    width: "120px"
  , 
    field: "UnitsInStock",
    title: "Units In Stock",
    width: "120px"
  , 
    field: "Discontinued",
    width: "120px"
  , 
    command: ["edit", deleteButton(),deleteButton2("MasterDelete")],
    title: "&nbsp;",
    width: "200px"
  ],
  detailTemplate: kendo.template($("#detailGridTemplate").html()),
  detailInit: detailInit,
  editable: 
    mode: "popup",
    confirmation: false
  
);
<link href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.default.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2015.1.429/styles/kendo.common.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2015.1.429/js/kendo.all.min.js"></script>
<div id="grid"></div>
<div id="window"></div>
<script type="text/x-kendo-template" id="windowTemplate">
  Delete <strong>#= ProductName #</strong> ?</p>
  <button class="k-button" id="yesButton">Yes</button>
  <button class="k-button" id="noButton">No</button>
</script>

<script type="text/x-kendo-template" id="detailGridTemplate">
  <div id="detailGrid"></div>
</script>

【讨论】:

我不会将此行为称为错误。看我的回答。【参考方案3】:

我不会将此问题称为错误。您正在经历的是事件传播。您的详细删除按钮和主删除按钮共享相同的名称,并且 Kendo UI 使用此名称作为与元素类名称(即'k-grid-Delete')关联的事件的一部分,正如您所知道的。

当您在子级(详细信息按钮)上触发点击事件时,它会向上传播 DOM 树。瞧,随着事件冒泡,它找到了一个具有相同类名的主删除按钮,因此,它的点击事件也会触发。

要停止这种行为,请在删除按钮的单击事件中停止传播。

var deleteButton = function() 
  return 
    name: "Delete",
    click: function(e) 
      // insert this line - it stops the event from bubbling up the DOM tree
      e.stopPropagation();

      var grid = this;
      var row = $(e.currentTarget).closest("tr");
      var data = this.dataItem(row);
      dWindow.content(windowTemplate(data));
      dWindow.open().center();

      $("#yesButton").click(function() 
        grid.removeRow(row);
        dWindow.close();
      );
      $("#noButton").click(function() 
        dWindow.close();
      );

      console.log('deleteButton hit!');
    
  ;
;

【讨论】:

感谢您的回答,但常规定义会创建相同的类元素并且它们都可以正常工作。如果我们忽略它,我们可能会遇到一些问题。 但是您没有使用常规定义(即"destroy")。您正在创建自定义操作,因此,框架希望您自己处理此类条件。

以上是关于Kendo UI Grid Master 和 Detail 按钮错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 kendo.ui.grid 中创建自定义 kendo.ui.Window 以进行编辑

kendo ui grid 动态控制某属性

Kendo UI Grid Angular (12)

Kendo UI Grid Ajax 破坏成功

如何提高kendo ui grid在页面的渲染速度

kendo ui 好用的小部件--grid