Подтвердить что ты не робот

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

У меня есть раскрывающийся список dojo (dijit) select, который вызывает функцию 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); 
    }

Спасибо, Джастин

4b9b3361

Ответ 1

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

  • Обновление dojo:).
  • Наследовать dijit.form.Select и "patch" функцию _updateSelection.
  • Расширьте dijit.form.Выберите и "исправьте" его прямо там.

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

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.

Ответ 2

Часто люди решают это, используя флаг priorityChange:

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

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

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

myWidget._lastValueReported=null;

Ответ 3

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

например:

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

Нет необходимости наследовать существующие функции dojo для этого или использовать отдельные внешние флаги. У виджета есть один встроенный для этого - "_onChangeActive" .