Работа с флажками из контроллера Javascript - PullRequest
2 голосов
/ 10 ноября 2010

Я создаю приложение на основе ajax.Сейчас я работаю с клиентским JavaScript.Я создал контроллер, который работает правильно в соответствии с логикой приложения, но у меня проблемы с обновлением представлений, которые содержат флажки.Вот краткий пример того, что я делаю:

<script type='text/javascript'>
    var model = { 'chk1': true, 'chk2': false, 'chk3': false };
    var Controller = {
        'processCheck': function(chk, value) {
            model[chk] = value;
            if (chk == 'chk2')
                model.chk2 = true;
            if (chk == 'chk3' && value)
                model.chk1 = false;
            if (chk == 'chk1' && model.chk3)
                model.chk1 = false;
            Controller.updateView();
        },
        'updateView': function() {
            $('#chk1').attr('checked', model.chk1);
            $('#chk2').attr('checked', model.chk2);
            $('#chk3').attr('checked', model.chk3);
        }
    }
</script>
<input id='chk1' type="checkbox" onclick="Controller.processCheck('chk1', $('#chk1').attr('checked')); return false;" />
<input id='chk2' type="checkbox" onclick="Controller.processCheck('chk2', $('#chk2').attr('checked')); return false;" />
<input id='chk3' type="checkbox" onclick="Controller.processCheck('chk3', $('#chk3').attr('checked')); return false;" />

Так что логика очень упрощена.Проблемы возникают, когда мы нажимаем на флажки.Они обновлены неправильно.Но если я вызываю методы контроллера с соответствующими параметрами, а затем проверяю модель, все кажется правильным.Так что проблема в событии click в флажках.У меня не было проблем с полями ввода и выпадающими списками.

Ответы [ 2 ]

3 голосов
/ 10 ноября 2010

Событие click на checkboxradio) странно и сбивает с толку.

В принципе, это происходит в момент взаимодействия с мышью, до того, как щелчок заставил флажок изменить свое состояние. Следовательно, должна быть возможность return false или event.preventDefault отменить действие по умолчанию для внесения этого изменения состояния. В этом случае состояние флажка никогда не должно касаться.

Однако в большинстве браузеров это не так. Из некоторой исторической причуды, восходящей к древнему Netscape, свойство checked флажка во время обработчика события click фактически является новым значением. Само событие click уже приводит к изменению состояния флажка. Затем, если вы запретите действие по умолчанию (return false), браузер скажет: «К сожалению, из-за этого изменения никогда не было», и активно вернет флажок обратно к его старому значению .

Это означает, что если вы намеренно установили состояние флажка из сценария в обработчике кликов, это значение будет потеряно из-за странной попытки браузера повернуть время вспять при изменении первоначального клика.

Итак, нелогично, если не набрать return false и предотвратить действие по умолчанию, это фактически заставит браузер меньше вмешиваться! Другое исправление:

setTimeout(Controller.updateView, 0);

вместо вызова updateView непосредственно в обработчике кликов. Это дает браузеру возможность перевернуть его состояние до того, как перезапишет его из модели. Вы даже можете поместить весь обработчик события, кроме return false, в 0-тайм-аут.

Теоретически правильным решением было бы использовать onchange вместо onclick. Это событие однозначно происходит после изменения состояния, поэтому вам не нужно беспокоиться об этой странности и совместимости браузера. Проблема с onchange в том, что IE запускает его не так быстро, как следовало бы; он ожидает фокусировки, чтобы переместиться из флажка перед выстрелом, как при вводе текста. Так что, по крайней мере, в этом браузере для согласованности вам понадобится вместо этого 0-timeout-on-click.

0 голосов
/ 10 ноября 2010

Диодей был на правильном пути, return false; вызывает ваши проблемы. Поскольку ваша updateView функция устанавливает все проверки каждый раз, вам не нужно беспокоиться о том, что она будет проверена на мгновение, поскольку все это произойдет быстрее, чем пользователь может увидеть в любом случае. При return false; настройка статуса checked в функции updateView для флажка, который щелкнул пользователь, будет игнорироваться.

Короче говоря, удалите return false; из всех функций onclick, и ваш код должен работать так, как вы хотите.

...