繁体   English   中英

Javascript:将自定义参数传递给回调函数

[英]Javascript: Passing custom arguments to a callback function

我有这个回调函数设置:

var contextMenu = [];
var context = [ { "name": "name1", "url": "url1" }, {"name": name2", "url: "url2" } ];
for(var i=0; i < context.length; i++) {
    var c = context[i];
    var arr = {};
    arr[c.name] = function() { callback(c.url); }
    contextMenu.push( arr );
}
function callback(url) {
   alert(url);
}

问题是传递给回调的url值始终是上下文变量中的最后一个值 - 在本例中为“url2”。 我期望将特定值传递给回调的每个“实例”,但由于回调似乎记住了相同的值,因此最后一次引用它。

我有点卡住了。 任何帮助,将不胜感激。

PS:我正在使用jQuery ContextMenu ,根据我的理解,它不支持将自定义数据发送到其回调函数。 正是在这种背景下,我遇到了这个问题。 在这种环境下要克服的任何建议也很有帮助!

使用额外的封闭。

arr[c.name] = (function(url) { 
    return function() { callback(url); }
})(c.url);

请参阅在循环中创建闭包:关于此主题的常见错误和大多数其他问题 ,现在您的问题也会添加到此池中。

您正在for循环中创建一系列闭包函数

arr[c.name] = function() { callback(c.url); }

并且它们都共享相同的范围,因此相同的c对象将指向循环结束后数组中的最后一个元素。

要解决此问题,请尝试执行以下操作:

arr[c.name] = function(url) {
    return function() { callback(url); };
}(c.url);

阅读更多关于闭包的信息: http//jibbering.com/faq/notes/closures/

一般解决方案

回调创建者助手

在循环中创建闭包创建了一个通用回调创建器 Anurag 在他的回答中指出的一个常见错误

回调创建者的参数

  • 函数的第一个参数是回调。
  • 每个其他参数都将作为参数传递给此回调。

传递回调的参数

  • 参数的第一部分来自您传递给回调创建者助手的参数(在我之前描述的第一个参数之后)。
  • 第二部分来自将由调用者直接传递给回调的参数。

源代码

//Creates an anonymus function that will call the first parameter of
//this callbackCreator function (the passed callback)
//whose arguments will be this callbackCreator function's remaining parameters
//followed by the arguments passed to the anonymus function
//(the returned callback).
function callbackCreator() {
    var functionToCall = arguments[0];
    var argumentsOfFunctionToCall = Array.prototype.slice.apply(arguments, [1]);
    return function () {
        var argumentsOfCallback = Array.prototype.slice.apply(arguments, [0]);
        functionToCall.apply(this, argumentsOfFunctionToCall.concat(argumentsOfCallback));
    }
}

用法示例

这是一个自定义AJAX配置对象,其成功回调使用我的回调创建者帮助程序。 使用响应文本,回调根据操作发生的行更新DataTables表中行的第一个单元格,并打印消息。

{
    url: 'example.com/data/' + elementId + '/generate-id',
    method: 'POST',
    successHandler: callbackCreator(function (row, message, response) {//Callback parameters: Values we want to pass followed with the arguments passed through successHandler.
            table.cell(row, 0).data(JSON.parse(response).text);
            console.log(message);
        },
        $(this).parents('tr'),//Row value we want to pass for the callback.
        actionName + ' was successful'//Message value we want to pass for the callback.
    )
}

或者在你的情况下:

arr[c.name] = callbackCreator(function(url) {
        callback(url);
    },
    c.url
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM