使用回调创建动态JSON数组(内部闭包问题)

时间:2013-09-17 17:34:38

标签: javascript callback closures

非常难以称呼此事。我正在为jQuery使用contextMenu插件。

http://joewalnes.com/2011/07/22/a-simple-good-looking-context-menu-for-jquery/

它可以采用一系列项目,因此我可以基于我之前建立的JSON对象动态创建菜单,该JSON对象之前称为“包”,只不过是包含id和title的JSON对象数组。例如:

var packages = [{id:1,title:"One"},{id:2,title"Two"}];

正如您可能从我添加的链接中的示例中看出的那样,“item”至少包含一个标签和一个回调函数(在选择该项时执行)。所以我的第一个想法是这样做:

var itemsArr = new Array();
for(var i=0; i<packages.length; i++)
{
    itemsArr.push({label:packages[i].title, action:function(){myClickFunction(packages[i].id);}});
}
$("#myMenuThingie").contextPopup({title:"My Popup", items:itemsArr});

现在,我已经验证我可以,事实上传递一个数组来使这个菜单正常工作。我认为,问题在于内部封闭问题。因为myClickFunction总是获取最后一个id的值,无论点击什么。

我在这里找到了一篇关于“立即调用函数表达式”的文章:http://benalman.com/news/2010/11/immediately-invoked-function-expression/,导致了这一修改:

for(var i=0; i<packages.length; i++)
{
    itemsArr.push({label:packages[i].title, action:(function(tempId){myClickFunction(tempId);})(packages[i].id)});
}

但是,该方法不会真正起作用,因为它会立即调用这些函数,而不是单击。

我知道我可以尝试使用jQuery来查找下拉列表生成的所有跨度并以这种方式应用单击事件,我只是想知道是否有一种方法来创建这个对象数组,其中回调引用了正确的ID。如果它允许我以类似的方式动态应用项目,我还会为其他contextMenu插件提供建议。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我可能会创建一个独立的函数来将包提供给数组。像这样:

var itemsArr = new Array();
function addToArray(package) {
    itemsArr.push({label:package.title, action:function(){myClickFunction(package.id);}});
} 
for(var i=0; i<packages.length; i++)
{
    addToArray(packages[i]);
}
$("#myMenuThingie").contextPopup({title:"My Popup", items:itemsArr});