Вы можете поместить код, который должен ссылаться на правильную версию i
, в замыкание, подобное этому:
var i = 0;
$('a#add-product').click(function(event){
i++;
// Begin closure. When called (at the end of the closure) it receives
// the current value of "i". This value of "i" will be referenced
// throughout the closure as a local variable containing the value
// you expect, instead of the "shared" "i" variable outside the
// closure.
(function( i ) {
// So basically we've created a new "scope" inside here. Now "i"
// is a separate local variable than the "i" variable ouside
// the closure. You could change the variable name by changing
// the parameter above. Like (function( my_i ) {...
// If you did that, you would need to change the "i" in your .change()
// handlers to "my_i". The rest of them could stay the same, or you
// could change them. Either way would work.
// This is because the .change() handlers are executed at a later time
// (and so are the AJAX callbacks) so they need to use the variable
// that is local to this closure.
// The rest of the code, like $("#selectionresult-" + i) is executing
// immediately, so it could reference the "i" variable that is
// outside the closure, and still work properly.
$('<div />').addClass('product').attr('id', 'product'+i)
.append($('<h2><img src="<?php echo base_url();?>img/product.png" alt="" />Product '+i+'</h2>'))
.append($('<div class="info-line"><label>Division</label><p><select id="selection-'+i+'" class="selection"><option value="">- Select a Division -</option><option value="abrasives">Abrasives</option><option value="tapes">Bonding, Surface Protection & Tapes</option><option value="packaging">Packaging</option></select></p></div>'))
.append($('<div class="info-line"><label>Category</label><p><select id="selectionresult-'+i+'" name="selectionresult-'+i+'" class="selectionresult"></select><span id="result-'+i+'" class="result"> </span></p></div>'))
.append($('<div class="info-line"><label>Product</label><p><select id="selectionresult2-'+i+'" name="selectionresult2-'+i+'" class="selectionresult2"></select><span id="result2-'+i+'" class="result2"> </span></p></div>'))
.append($('<a class="remove" href="#add-product" id="remove-product'+i+'"><img src="<?php echo base_url();?>img/remove-product.jpg" alt="" />Remove Product</a>'))
.appendTo("#products");
// START OF ADDITIONAL PRODUCT DROP DOWNS
$("#selectionresult-" + i).hide();
$("#selectionresult2-" + i).hide();
$("#selection-" + i).change(function () {
$(this).next(".selectionresult").hide();
$(this).next(".selectionresult2").hide();
$("#result-" + i).html('Retrieving ...');
$.ajax({
type: "POST",
data: "data=" + $(this).val(),
url: "<?php echo base_url();?>dropdown.php",
success: function (msg) {
if (msg != '') {
$("#selectionresult-" + i).html(msg).show();
$("#result-" + i).html('');
}
else {
$("#result-" + i).html('<em>No item result</em>');
}
}
});
});
$("#selectionresult-" + i).change(function () {
$(this).next(".selectionresult2").hide();
$("#result2-" + i).html('Retrieving ...');
$.ajax({
type: "POST",
data: "data=" + $(this).val(),
url: "<?php echo base_url();?>dropdown.php",
success: function (msg) {
if (msg != '') {
$("#selectionresult2-" + i).html(msg).show();
$("#result2-" + i).html('');
}
else {
$("#result2-" + i).html('<em>No item result</em>');
}
}
});
});
// End closure. Executes the closure function, passing in the
// current value of "i"
})( i );
});
EDIT:
Чтобы объяснить, что происходит, в javascript переменные, передаваемые (или создаваемые) в теле функции, являются локальными для этой функции и сохраняются.
Все, что я делаю выше, это создание функции, которая принимает один параметр. Здесь я изменю имя параметра, чтобы сделать его более понятным:
function( inner_i ) {
// create your element with the new local variable "inner_i"
}
... но я также вызываю эту функцию, как только я ее создаю:
(function( inner_i ) {
// create your element with the new local variable "inner_i"
})( i )
// ^------- call the function, passing in the "i" from your loop.
Синтаксис выглядит немного странно, но это просто способ вызова функции, которую вы только что создали.
Это было бы так же, как делать:
function myNewFunction( inner_i ) {
// creates your element with the new local variable "inner_i"
}
myNewFunction( i ); // Call the function we just created above,
// and pass the "i" from the loop into it