【问题标题】:Dynamic onClick added to dynamic buttons动态 onClick 添加到动态按钮
【发布时间】:2014-10-15 20:46:27
【问题描述】:

我正在使用 jqGrid 并将按钮动态添加到网格中。添加这些按钮后,在 gridComplete 属性中,我调用我的函数:

function(){
   var ids = jQuery("#dataTable").jqGrid('getDataIDs');
   for(var i=0;i < ids.length;i++){
        var cl = ids[i];
        $('.ui-loader.ui-corner-all.ui-body-a.ui-loader-default').remove();
        $('#create_' + cl).on('click', function() {
            var $popUp = $("<div/>").popup({
            dismissible : true,
            theme : "b",
            overlyaTheme : "e",
            transition : "pop"
            }).on("popupafterclose", function() {
            $(this).remove();
            }).css({
                'width' : '100%',
                'height' : '100%',
                'padding' : '5px'
            })
            $("<a>", {
                text : "Edit",
            }).buttonMarkup({
                inline : false,
                mini : true,
            }).on("click", function() {
                $popUp.popup("close");
                $('#dataTable').jqGrid('editGridRow', cl);
            }).appendTo($popUp);

            $("<a>", {
                text : "Delete"
            }).buttonMarkup({
                inline : false,
                mini : true,
            }).on("click", function() {
                $popUp.popup("close");
            }).appendTo($popUp);

            $popUp.popup('open').trigger("create");
            });
}

除了一个问题外,它工作正常。似乎动态按钮都接收相同的功能(单击第一行中的按钮调用最后一行应该调用的内容,单击第二个按钮调用最后一行的功能,等等......) 因此,似乎我无法将 onclick 动态分配给大量按钮。当我想到它时,我开始认为应该可以通过这种方式为每个按钮分配单击方法,但我不太确定,因为我是 jquery/jqgrid 的新手。有没有什么办法解决这一问题?

这是我添加按钮的代码:

function displayButton(cellvalue, options, rowObject){var act = "<div id='page_" + options.rowId + "'> <a href='#' data-role='button' id='create_"+ options.rowId +"'>Create a popup</a></div>"
    return act; return act;}

由jqgrid所在行的模型调用。

formatter: displayButton

【问题讨论】:

  • 我遇到了同样的问题,因为它们都是用你创建的最后一个方法设置的,对吧?尝试使用递归函数而不是 for 循环来创建按钮。
  • 请不要按照上述评论的建议尝试通过递归来解决这个问题。您可能会想出一种方法来完成这项工作,但对于解决简单的函数闭包问题是完全没有必要的。

标签: javascript jquery html jqgrid


【解决方案1】:

问题是您在处理函数中使用的变量cl 绑定到函数外部声明的同一个变量。当您遍历循环时,cl 的值会发生变化,但您添加的函数不会发生变化。

循环内变量闭包的错误是一个常见的 Javascript 编程问题,无论何时在循环内声明函数时都需要注意。 Javascript 中没有“块作用域”(如 Java),只有“函数作用域”。

基本上,模式:

for (var i=0; i<len; i++) {
    foo.on('click', function() {
        console.log(i);
    });
}

将始终为 i 使用相同的值 - 循环中的最后一个值。这几乎总是不是程序员想要的,可以通过这个修改来解决:

for (var i=0; i<len; i++) {
    foo.on('click', (function(bound_i) { 
        return function() {
            console.log(bound_i);
        };
    })(i));
}

在这种情况下,循环的每次迭代都会为i 创建一个具有不同值的新函数,并绑定到变量bound_i)。

将此模式应用于上面我看到此问题的代码:

....
.on("click", function() {
   $popUp.popup("close");
   $('#dataTable').jqGrid('editGridRow', cl);
 })
 ....

变成

....
.on("click", (function(bound_cl) {
   return function() {
       $popUp.popup("close");
       $('#dataTable').jqGrid('editGridRow', bound_cl);
   };
 })(cl));
 ....

如需进一步参考,请参阅this related question

【讨论】:

  • 非常优雅,工作完美,解释也很好。非常感谢。
猜你喜欢
  • 2011-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-07
  • 1970-01-01
  • 2020-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多