jQuery/JavaScript在循环中分配点击事件(闭包?)

3

可能是重复问题:
JavaScript循环内的闭包 - 简单实用示例

我正在为“仪表板”网页创建一个状态表。每个状态都处于“开启”或“关闭”状态。

我尝试使用jQuery button/buttonset来拥有开关/切换控件,以允许用户切换状态的值。我通过ajax数据库查询动态创建表格和按钮。

我基本上正在尝试在用户单击其中一个按钮时触发ajax查询,但我无法正确地分配单击事件。

我的第一次尝试使最终列表值在单击任何按钮时都会触发。

因此,啊哈!这是一个标准的“JavaScript闭包”问题。(我这么认为...)

进一步的尝试毫无结果,而且我对闭包问题的理解还不足以弄清楚为什么我的技术是错误的。

这是我想要调用的代码:

function SetStatus(item, status) {
    var params = '{itemName: "' + item + '", status: "' + status + '"}';
    $.ajax({
        type: "POST",
        url: "WebServices/Dashboard.asmx/SetItemStatus",
        data: params,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: StatusSet,
        error: ShowError
    });
}

这是我正在尝试的代码的当前版本:

$(itemOnButton).click(
    function (_item) {
        SetStatus(_item, 'On');
    } (itemName)
);

结果是在从数据库获取结果后(甚至在它们显示之前),最后一个状态为 'On' 的项目会立即触发 SetStatus 事件。
我知道这很简单,但我仍然相信它是基本的闭包问题,但我一直在苦思冥想!感谢您的帮助!
1个回答

6
$(itemOnButton).click(
    function (_item) {
        SetStatus(_item, 'On');
    } (itemName)
);

目前你在将'closure'函数赋值给click时会触发它。尝试:

$(itemOnButton).click(
    function (ev) { 
        // this is the clicked element
        // ev is the event object

        // how do you get the name?
        // var itemName = $(this).attr("name");

        SetStatus(itemName, 'On');
    }
);

您也可以这样做。
$(itemOnButton).click(
    function (_item) {
        return function (ev) {
            SetStatus(_item, 'On');
        };
    } (itemName)
);

现在它像你一样触发,但不会立即执行,而是返回用于处理单击事件的函数。
返回的事件处理函数现在是_item的闭包。匿名函数是由参数设置为itemName的_item的作用域。

你的第一个示例已经消除了自动点击,但是无论按钮如何,仍然只传递了最后一个项目。第二个示例是让页面正常工作的关键。谢谢! - mbm29414
不用谢。还可以阅读stackoverflow上的这个非常好的答案 - metadings

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接