Событие Dojo Select onChange срабатывает при программном изменении значения

У меня есть раскрывающийся список выбора dojo (dijit), который вызывает js-функцию onChange. Я ожидал, что это вызовет функцию onChange только тогда, когда пользователь изменяет значение в раскрывающемся списке, однако он даже вызывает функцию onChange, когда я программно изменяю значение раскрывающегося списка из кода js. Как мне заставить его вызывать функцию только тогда, когда пользователь изменяет значение раскрывающегося списка? Он не должен вызывать функцию, когда я программно меняю значение.

<select jsId="ddlBoundaryType" id="ddlBoundaryType" name="ddlBoundaryType" 
                            dojoType="dijit.form.Select">
                            <option value="0">Circle</option>
                            <option value="1">Polygon</option>
                        </select>

dojo.addOnLoad(InitBoundaries);
    function InitBoundaries() {
        dojo.connect(dijit.byId("ddlBoundaryType"), 'onChange', Boundaries_ChangeBoundaryType); 
    }

person Justin    schedule 12.07.2010    source источник
comment
Не могли бы вы опубликовать код, который программно изменяет значение раскрывающегося списка?   -  person Abboq    schedule 14.07.2010
comment
dijit.byId (ddlBoundaryType) .attr ('значение', 0);   -  person Justin    schedule 14.07.2010


Ответы (3)


Я думаю, что правильным решением в этом случае для вас будет http://bugs.dojotoolkit.org/ticket/10594, поскольку он имеет дело непосредственно с dijit.form.Select. Конечно, есть несколько способов исправить это.

  1. Обновите додзё :).
  2. Наследуйте dijit.form.Select и "исправьте" функцию _updateSelection.
  3. Расширьте dijit.form.Select и "пропатчите" его прямо там.

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

dijit.form.Select.extend({
   _updateSelection: function() {
        this.value = this._getValueFromOpts();
        var val = this.value;
        if(!dojo.isArray(val)){
            val = [val];
        }
        if(val && val[0]){
            dojo.forEach(this._getChildren(), function(child){
                var isSelected = dojo.some(val, function(v){
                    return child.option && (v === child.option.value);
                });
                dojo.toggleClass(child.domNode, this.baseClass + "SelectedOption", isSelected);
                dijit.setWaiState(child.domNode, "selected", isSelected);
            }, this);
        }
   }
});

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

myWidget.attr('value', newValue, false) // should now work without firing onChange.
person Anh-Kiet Ngo    schedule 18.08.2010
comment
# 1 не вариант, так как dojo версии 1.5, а она идет в 1.6. Я посмотрю на №3, спасибо! - person Justin; 21.08.2010
comment
Мля, не заметил, что это для 1.6, бух! - person Anh-Kiet Ngo; 22.08.2010

Часто люди решают эту проблему с помощью флага priorityChange:

myWidget.set("value", 1234, false);

Это решит вашу проблему, за исключением тонких проблем, когда значение изначально равно 123, вы программно устанавливаете его на 456, а затем пользователь устанавливает его обратно на 123, и в этом случае не будет события onChange () для действия пользователя. или.

По этой причине вы можете дополнительно:

myWidget._lastValueReported=null;
person Bill Keese    schedule 15.07.2010
comment
set не является функцией, я пробовал dojo.byId, dijit.byId, и это для доступа к нему, и ни у одной из них нет этой доступной функции. - person Justin; 26.07.2010
comment
_Widget.set () - новая функция в версии 1.5. До 1.5 он назывался attr (). Обратите внимание, что эта проблема исправлена ​​в bugs.dojotoolkit.org/ticket/10988 для додзё. 1.6, но поскольку он не будет выпущен в ближайшее время, попробуйте обходной путь, описанный выше. - person Bill Keese; 02.08.2010
comment
Спасибо, но, к сожалению, это не работает (по крайней мере, в dojo 1.4.2.) Установка 3-го параметра .attr () на false не дала никакого эффекта, он по-прежнему вызывает событие onchange. Кроме того, установка _lastValueReported = null вызывает событие onchange во второй раз ... - person Justin; 02.08.2010
comment
@BillKeese извиняюсь за беспокойство по этому старому вопросу. Я хотел бы спросить вас, может ли использование _setValueAttr в dojo 1.10.4 быть альтернативой .set(). Вы знаете, если _setValueAttr вызывает проблемы со значением _lastValueReported? Спасибо за ваш опыт по этой теме. - person GibboK; 23.05.2017
comment
Вопрос, связанный с @BillKeese stackoverflow.com/questions/44115583/ - person GibboK; 23.05.2017
comment
Думаю, вы могли бы, но я не знаю, зачем вам это нужно. set () - официальный метод. - person Bill Keese; 25.05.2017

Гораздо более простой способ заключается в том, что я хотел бы предложить флаг «_onChangeActive», который не рекомендуется использовать, поскольку он служит внутренним целям. Но, если потребуется, мы могли бы это использовать. «_onChangeActive» - это флаг, присутствующий в виджетах dojo Select type, для которого по умолчанию установлено значение true. Если для этого флага установлено значение true, событие onChange запускается как обычно. Но если для него установлено значение false, событие onChange не запускается, когда значение изменяется либо пользователем, либо программно.

e.g:

var widget = registry.byId('widget_id');
widget.set('_onChangeActive', false); // setting the flag to false
...//make changes to the select programatically
widget.set('_onChangeActive',true); // setting back to true after programatic changes are done

Для этого не нужно наследовать существующую функциональность додзё или использовать отдельные внешние флаги. Для этого в виджет встроен один - "_onChangeActive".

person vivek_nk    schedule 06.09.2013