2014-02-06 5 views
1

Я вызываю функцию, как показано ниже. Здесь я также передаю функцию обратного вызова, которая должна быть вызвана только после того, как конкретная форма не будет представлена ​​до этого.Передача функции обратного вызова в качестве параметра

<div onClick="myNamespace.openDialog(par1,par2,myNamespace.callback(myNamespace.cb,'p1','p2'))">OPEN DIALOG</div> 

var myNamespace = myNamespace || {}; 
myNamespace={ 
    return{ 
     cb:function(p1,p2){alert(p1+" cb "+p2);}, 
     callback:function(f){f(arguments[1],arguments[2]);}, 
     openDialog:function(p1,p2,f){ 
      // aboutBizzNs.cb should be called here only after form submit 

     } 
    } 
}(); 

Проблема заключается alert(p1+" cb "+p2); вызывается только после того, как OPEN DIALOG нажата. Это не должно быть так. Его нужно называть только тогда, когда я хочу. В чем проблема

ответ

0

Проблема заключается в том, что aboutBizzNs.callbackнемедленно вызывает функцию, предоставленную в качестве аргумента.


Сравнить с нижеследующим, который создает и возвращает closure (function), который будет вызывать функцию, поставляемый когда он iself вызывается:

callback: function(f){ 
    // The f variable is bound in a closure below, which is returned immediately. 
    // However, the f function is NOT invoked yet. 
    // We also copy the arguments of this function invocation and expose 
    // them via a variable which is also bound in the following closure. 
    var boundArgs = Array.prototype.slice(arguments, 0); 
    return function() { 
     // Now f is invoked when this inner function is evaluated, which 
     // should be in response to the event. 
     return f(boundArgs[1], boundArgs[2]);} 
    } 
} 

Я бы также использовать apply, как в следующем примере, например, чем произвольное число "связаны" параметры могут быть использованы ..

return function() { 
    return f.apply(this, boundArgs.slice(1)); 
} 

.. но Thi s является довольно распространенной операцией и уже поддерживается Function.prototype.bind (который является частью ES5 и может использоваться в других браузерах). Таким образом, оригинальный ..

myNamespace.callback(myNamespace.cb,'p1','p2') 

.. может быть записан как ..

myNamespace.cb.bind(this,'p1','p2') 

.. для того же эффекта здесь. Разница заключается в том, что внутри функции обратного вызова (cb) может отличаться, поскольку bind не разрешает «пройти» от this.

Или просто забыть обо всех этих специальных функций и просто обернуть обратный вызов как таковой ..

function() { myNamespace.cb('p1','p2') } 
+0

после прохождения через ваши аргументы и детали, я обнаружил, что передача 'функцию() {myNamespace.cb ('p1 ',' p2 ')} 'как аргумент' openDialog (....., f) ', а затем вызвать' f() 'внутри' openDialog() 'было достаточно для меня. Спасибо – manish

+0

@Manish You' приветствуется! Закрытие (и функции как первоклассные значения) немного сложнее освоить, но как только вы их освоите, вы являетесь мастером JavaScript ;-) – user2864740

Смежные вопросы