Сделать ссылочную переменную javascript переменной значения? - PullRequest
1 голос
/ 04 февраля 2010

У меня есть функция JavaScript, которая выглядит примерно так:

function doSomething(me) {
        var isMeChecked = me.checked;
        for (i=0;i<=10;i++) {
            me.checked = !isMeChecked;
            alert (me.checked);
        }
    }

Я предполагал, что isMeChecked останется постоянным после первой загрузки, но, по-видимому, это ссылочная переменная для me.checked, и поэтому она меняется с каждой итерацией. Как заставить isMeChecked установить значение me.checked при первой загрузке, а не ссылку me.checked?

Хорошо, чтобы сделать это более ясным, я редактирую этот пост, чтобы показать действительный код, который демонстрирует нежелательное поведение:

Вот функции javascript:

function CheckAll(me, gridViewId) {
    var isMeChecked = (me.checked)?true:false;
    alert('CheckAllFired_1');
    Parent = document.getElementById(gridViewId);
    for (i = 0; i < Parent.rows.length; i++) {
        alert('CheckAllFired_2_' + i.toString());
        var tr = Parent.rows[i];
        var td = tr.childNodes[0];
        var item = td.firstChild;
        if (item.id != me.id && item.type == "checkbox") {
            alert('CheckAllFired_3_' + i.toString() + '_' + me.checked + '_' + isMeChecked);
            item.checked = !isMeChecked;
            item.click();
        }
    }
}
function CheckSelectAll(me, checkBoxHeaderId, gridViewId) {
    alert('CheckSelectAllFired_1');
    if (!me.checked) {
        alert('CheckSelectAllFired_2');
        document.getElementById(checkBoxHeaderId).checked = false;
        return;
    }
    else {
        alert('CheckSelectAllFired_3');
        document.getElementById(checkBoxHeaderId).checked = true;
        Parent = document.getElementById(gridViewId);
        for (i = 0; i < Parent.rows.length; i++) {
            alert('CheckSelectAllFired_4_' + i.toString());
            var tr = Parent.rows[i];
            var td = tr.childNodes[0];
            var item = td.firstChild;
            if (item.type == "checkbox") {
                alert('CheckSelectAllFired_5_' + i.toString());
                if (!item.checked) {
                    alert('CheckSelectAllFired_6_' + i.toString());
                    document.getElementById(checkBoxHeaderId).checked = false;
                    return;
                }
            }
        }
        return;
    }
}

У меня есть сетка вида asp.net. Первый столбец является столбцом флажков, с флажком в заголовке, а также переключает «Выбрать / Отменить выбор всех» других флажков в столбце. Флажок в заголовке имеет событие onclick, установленное на onclick="CheckAll(this, 'myGridViewClientID')"

Все остальные флажки в сетке имеют событие onlick, установленное на onclick="CheckSelectAll(this, 'headerCheckBoxID', 'myGridViewClientID'"

И headerCheckBoxID, и myGridViewClientID устанавливаются в коде, когда визуализация сетки отображается.

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

Однако я также хотел, чтобы дочерние флажки имели следующее поведение: 1) Если какой-либо из них не отмечен, снимите флажок «выбрать все». 2) Если все они отмечены, установите флажок «выбрать все».

Теперь, поскольку событие click дочерних флажков имеет возможность изменить проверенный статус headercheckbox, когда цикл возвращается обратно к событию "checkall", состояние headercheckbox отличается от того, когда оно впервые запускалось, и таким образом он заканчивает тем, что проверял только первый дочерний флажок при попытке сделать выбор всех.

Используя оповещения, я смог увидеть, что когда проверенное состояние headercheckbox изменяется в функции CheckSelectAll, это значение также изменяется для значения «isMeChecked» в функции CheckAll, которая порождает функции CheckSelectAll.

Тогда это выглядит очень похоже на ссылочную переменную. Я не знаю, как этому помешать.

Ответы [ 4 ]

4 голосов
/ 04 февраля 2010

Подумай об этом. предположим, x.checked = true. запустите doSomething (x). Когда функция запускается, me.checked имеет значение true. Теперь посмотрим на ваш цикл:

Пропуск 1: me.checked - правда. так isMeChecked это правда. так что вы установили me.checked в false.

Пропуск 2: me.checked является ложным. isMeChecked все еще верно, потому что вы не меняете его внутри цикла. поэтому для me.checked снова установлено значение false.

Пропуск 3: см. Пропуск 2. ...

При выходе из функции isMeChecked имеет значение true, а me.checked - значение false. Все, что вы сделали, это установили me.checked в false 10 раз. Дело не в том, что isMeChecked является ссылкой (потому что это не так), а просто в вашей логике, если вы ожидали других результатов.

0 голосов
/ 04 февраля 2010

Ваш цикл просто оборван - Прочитайте комментарии

// doSomething({checked:true});
function doSomething(me) {
    // isMeChecked = true;
    var isMeChecked = me.checked;
    for (i=0;i<=10;i++) {
        // me.checked = false ... always...
        me.checked = !isMeChecked;
        alert (me.checked);
    }
}
0 голосов
/ 04 февраля 2010

Если я не сумасшедший, в javascript нет такой вещи, как ссылка на логическое значение.Они всегда передаются по значению.Можете ли вы вставить полный пример кода, который мы можем запустить без заполнения каких-либо пробелов?

0 голосов
/ 04 февраля 2010

Вы можете сделать var isMeChecked = me.checked?true:false;

Кроме того, me.checked != isMeChecked - это не то же самое, что me.checked = !isMeChecked, что, вероятно, и предполагалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...