Получить значение переменной в цикле - PullRequest
0 голосов
/ 16 августа 2010

У меня есть цикл, который, когда он вызывается, создает div с некоторыми элементами формы в них.Каждый элемент div основан на переменной «i», которая присваивает уникальные имена полям и элементам div.Есть ли способ, которым я могу сохранить то, что переменная была в момент создания div?

Например, div1 создан, и у всего в нем есть 1 (переменная), присоединенная к имени.Элементы формы опираются друг на друга и вызываются по ID.Проблема в том, что когда я создаю новый div и переменная (i) изменяется на 2, первый набор элементов формы пытается использовать 2 вместо 1.

Имеет смысл?

ПравитьВот кодЭто довольно грязно, поэтому я заранее извиняюсь.

    var i = 0;

    $('a#add-product').click(function(event){
        i++;
        $('<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 &amp; 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">&nbsp;</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">&nbsp;</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>');
                                }
                            }
                        });
                    });
    });

Ответы [ 4 ]

2 голосов
/ 16 августа 2010

Вы можете поместить код, который должен ссылаться на правильную версию 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 &amp; 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">&nbsp;</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">&nbsp;</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
0 голосов
/ 16 августа 2010

На самом деле, более простой ответ - хранить целое число как значение для каждого создаваемого вами элемента.Спасает вас от возни с замыканиями и намного удобнее в обслуживании.В вашем цикле просто выполните:

newElement.data("myIndex", i);

и снова получите индекс:

newElement.data("myIndex");

Или, если в обработчике события:

$(this).data("myIndex");
0 голосов
/ 16 августа 2010

Из того, что я могу понять, элементы в div1 относятся друг к другу, но не к элементам в div2. Вопрос в том, КАК они относятся друг к другу? Если это происходит по событиям, например по событию onchange текстового поля, вы можете сделать следующее:

var MAX = 10;
for (var i = 0; i < MAX; i++) {
    // Create textbox
    $("<input type='text'>").attr("name", "slave" + i);
    // Create a second textbox that, when changed, takes it's value,
    // makes it uppercase, and copies it to the first one
    $("<input type='text'>").attr("name", "master" + i)
    .change(
        (function(i) {
            function() {
                $("input[name=slave" + i + "]").text($(this).text());
            }
        })(i)
    );
}

Создает временную область, которая фиксирует значение i внутри себя:

        (function(i) {
            function() {
                // the value of i is frozen in time within here
            }
        })(i)
0 голосов
/ 16 августа 2010

Используйте отдельную переменную для хранения индекса, используя цикл для добавления к нему.

Грубо говоря, функция с циклом (независимо от того, вызывает ли она другую функцию с номером индекса или нет,не имеет значения) но таким образом вы сохраняете значение индекса и используете свои циклы, чтобы не было дубликатов.

var uniqueIndex = 0;

function functionWithLoop(x)
{
    for (i=0; i<x; i++)
    {
        uniqueIndex++;
        createNewDivFunction(uniqueIndex);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...