【问题标题】:KendoUI Grid Master And Detail Buttons BugKendo UI Grid Master 和 Detail 按钮错误
【发布时间】: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,我针对这种情况发布了一个示例。

标签: kendo-ui kendo-grid master-detail kendo-ui-grid


【解决方案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")。您正在创建自定义操作,因此,框架希望您自己处理此类条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-27
    • 2020-11-04
    相关资源
    最近更新 更多