0

我正在努力通过 JSON 数组动态生成按钮。

精简代码是这样的(目的是根据数据构建一个表,还没有什么花哨的,我还不精通这个):

$.ajax({
    /* type, content, etc. removed */
    success: function (data, textStatus, XmlHttpRequest) {
        var target = $('myContainerDiv');
        var result = data.d.results;

        var $table = $('<table />');
        for(var i=0;i < results.length; i++) {
            var $row = $('<tr />');
            var $cell = $('<td />');
            var $button = $('<input />').attr({ type: 'button', value: 'Edit', name: 'btn' + i });
            $button.click(function () {

                // **
                // In a .NET environment, this would become a closure
                // I suspect this is the offending bit of code
                //

                alert(results[i].name);

            };

            $cell.append($button);
            $row.append($cell);
            $table.append($row);
        }

        $target.append($table);
    },
    /* error etc. removed*/
});

我基本上想要一个充满按钮的列,每个按钮都会从我从$.ajax调用中获得的数组中弹出一个字段的值。

按钮实际上出现了,但它们对单击没有反应,而且我在 F12 工具控制台中没有看到运行时错误。这可能是因为该脚本是 Microsoft Dynamics CRM 2011 解决方案配置页面的一部分,但除此之外,我确信 AJAX 调用正常(我尝试让它打印出数据,我可以看到)。

更新

在点击处理程序中引用i确实是有问题的行:像这样更改代码使事情按我的预期工作:

var $button = $('<input />').attr({ type: 'button', value: 'Edit', name: 'btn' + results[i].name });
$button.click(function () {
    // 'i' value is NOT what I thought it was !
    alert(this.name.substring(3,this.name.length));
    // I found out in the meanwhile that 'this' references the event source
};
4

3 回答 3

1

首先,您的代码中有几个语法错误,它可能根本没有运行:

  1. 如果你的 div 容器的 ID 是myContainerDiv, 来获取你需要做的目标$('#myContainerDiv')

  2. 您创建了一个变量result,但您使用了一个results变量

  3. 你没有在$button.click

  4. 您正在添加所有内容,$target但被定义为target

现在实际问题可能是,正如您所说,闭包,请记住您关闭了变量而不是值,因此当您执行按钮单击处理程序时,i其值为results.length,所以到那时您已超出范围。

您可以尝试将results对象存储在其他位置,从按钮中提取您要查找的对象的 Id(您正在命名 then 'btn'+i),然后以name这种方式访问​​该属性。

于 2012-09-13T16:27:09.273 回答
0

我注意到您没有关闭 .click() 括号。

尝试...

$button.click(function () {
    alert(results[i].name);
});
于 2012-09-13T16:24:29.807 回答
0

你可以试试这个...

$.ajax({
/* type, content, etc. removed */
success: function (data, textStatus, XmlHttpRequest) {
    var $target = $('#myContainerDiv'),
        results = data.d.results,
        $table = $target.append('<table />').children('table:last-child'), $trSet = $([]);
    for(var i=0; i < results.length; i++) {
        $trSet = $trSet.add(
            $([
                '<tr><td>',
                $('<input type="button" value="edit" name="btn'+i+'" rel="'+results[i].name+'" />').wrap('<div />').html(),
                '</td></tr>'
            ].join(''))
        );
    }       
    // Using Event delegation ... Only one handler is attached to the DOM.
    $table.append($trSet).click(function(e){
        var $t = $(e.target);

        if( $t.is('input[type="button"]') ){
            alert($t.attr('rel'));
        }
        // choose to return false whether to prevent event bubbling up the DOM or not
        // return false;
    });     
  },
   /* error etc. removed*/
});
于 2012-09-13T16:59:02.587 回答