2011-02-17 20 views
35

Estoy trabajando en una aplicación que presentará encuestas al usuario. El marcado se ve algo como esto:Pasar parámetros adicionales a jQuery cada() devolución de llamada

<body> 
    <div class="question" id="q1"> 
     Question 1 
    </div> 
    <div class="question" id="q2"> 
     Question 2 
    </div> 
    <!-- etc --> 
</body> 

Quiero construir los objetos JavaScript desde el DOM con jQuery, por lo que en el Survey constructor que estoy atravesando el jQuery establece utilizando el método each(). El problema es que dentro de la función de devolución de llamada no puedo obtener una referencia al objeto Survey para adjuntar cada objeto Question a la matriz Survey.questions. ¿Cómo se puede obtener una referencia al objeto Survey? ¿Hay alguna manera de pasar un parámetro adicional (por ejemplo, una referencia al objeto Survey) a la función de devolución de llamada?

function Survey() { 
    this.questions = new Array; 
    $('.question').each(function(i) { (/* Survey object */).questions.push(new Question(this)); }); 
} 

function Question(element) { 
    this.element = $(element); 
} 

Respuesta

29

Debería poder crear una referencia a su encuesta antes de repetir las preguntas.

function Survey() { 
    this.questions = new Array(); 
    var survey = this; 
    $('.question').each(function(i) { 
     survey.questions.push(new Question(this)); 
    }); 
} 

function Question(element) { 
    this.element = $(element); 
} 

var survey = new Survey(); 

$.each(survey.questions, function() { 
    $("ul").append("<li>" + this.element.text() + "</li>"); 
}); 

Ejemplo de trabajo en jsfiddle

+1

Gracias! +1 para [jsfiddle.net] (http://www.jsfiddle.net) – MarioVW

15

Aunque esto puede no ser la respuesta correspondiente, pero dado que la cuestión es cómo pasar parámetros a jQuery cada función.

Primer acercamiento: Utilizar la función parcial - more on this y desde closure library

jsfiddle:

var param = 'extra-param'; 

var partial = function(fn, var_args) { 
    var args = Array.prototype.slice.call(arguments, 1); 
    return function() { 
    // Clone the array (with slice()) and append additional arguments 
    // to the existing arguments. 
    var newArgs = args.slice(); 
    newArgs.push.apply(newArgs, arguments); 
    return fn.apply(this, newArgs); 
    }; 
}; 

$(['joe','james','rick','kirk']).each(partial (function (index,value) { 
    alert(arguments.length); 
    alert(arguments[0]); 
},param)); 

segundo enfoque es función

$ .Cada puede tomar cualquiera de 2 parámetros Index y Element (Que también se puede denominar como this) O si no es necesario Index entonces puede pasar como argumento para Array $ .Cada y el elemento puede referido como este

PRECAUCIÓN: args es sólo para uso interno - por jQuery

// Execute a callback for every element in the matched set. 
// (You can seed the arguments with an array of args, but this is 
// only used internally.) 
each: function(callback, args) { 
    return jQuery.each(this, callback, args); 
}, 

que llamará each: function(obj, callback, args)

luego llamar callback.apply(obj[ i ], args); si pasa matriz como argumento OTH erwise callback.call(obj[ i ], i, obj[ i ]);

tenga en cuenta la diferencia de aplicar y llamar Código de ejemplo

: http://jsfiddle.net/dekajp/yA89R/1/

var param = 'rick'; 
$(['joe','james','rick','kirk']).each(function (arg1 , arg2 ,arg3) { 
    //alert('[this: '+this +'] [arg1: '+ arg1 +'] [arg2:'+arg2+'] [param:'+param+']'); 
},['hello 1','hello 2','hello 3']); 

Para referencia jQuery Cada versión Código 1,9

// args is for internal usage only 
    each: function(obj, callback, args) { 
     var value, 
      i = 0, 
      length = obj.length, 
      isArray = isArraylike(obj); 

     if (args) { 
      if (isArray) { 
       for (; i < length; i++) { 
        value = callback.apply(obj[ i ], args); 

        if (value === false) { 
         break; 
        } 
       } 
      } else { 
       for (i in obj) { 
        value = callback.apply(obj[ i ], args); 

        if (value === false) { 
         break; 
        } 
       } 
      } 

     // A special, fast, case for the most common use of each 
     } else { 
      if (isArray) { 
       for (; i < length; i++) { 
        value = callback.call(obj[ i ], i, obj[ i ]); 

        if (value === false) { 
         break; 
        } 
       } 
      } else { 
       for (i in obj) { 
        value = callback.call(obj[ i ], i, obj[ i ]); 

        if (value === false) { 
         break; 
        } 
       } 
      } 
     } 

     return obj; 
    }, 
+1

Esta respuesta es una discusión mucho más exhaustiva de los problemas planteados en la pregunta. – axlotl

7

me encontré con un problema similar.para pasar un parámetro para cada función:

var param1 = "one"; 
var param2 = "two"; 

var params = [ param1, param2 ]; 


$('#myTable > tbody > tr').each(function(index) { 

    var param1back = params[0]; 
    var param2back = params[1]; 

},params); 
+0

funcionó para mí. Solo quería recalcar que los params deberían ser siempre de tipo array. No funciona si params es de otro tipo. –

+0

Objeto JSON como parámetro funcionó para mí. – David

+0

gracias, funciona ,,, –

1

//Create extra data 
 
var dataArray = ["A", "B", "C"]; 
 

 
//Send default arguments from jQuery's each (index and item) along 
 
//with our new data argument to a named function handler. 
 
$("#myList").children().each(function(jqIndex, jqItem) 
 
          { 
 
           listItemsHandler(jqIndex, jqItem, dataArray[jqIndex]); 
 
          });  
 

 
//Named function handler accepting 3 arguments. 
 
function listItemsHandler(index, item, data) 
 
{ 
 
    console.log(index + " " + item + " " + data); 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<ol id = "myList"> 
 
    <li>First</li> 
 
    <li>Second</li> 
 
    <li>Third</li> 
 
</ol>

Cuestiones relacionadas