以编程方式更改值时触发 Dojo Select onChange 事件

Posted

技术标签:

【中文标题】以编程方式更改值时触发 Dojo Select onChange 事件【英文标题】:Dojo Select onChange event firing when changing value programmatically 【发布时间】:2010-07-12 15:27:41 【问题描述】:

我有一个调用 js 函数 onChange 的 dojo (dijit) 选择下拉菜单。我希望这只会在用户更改下拉列表中的值时调用 onChange 函数,但是,当我以编程方式从 js 代码更改下拉列表的值时,它甚至会调用 onChange 函数。当用户更改下拉值时,如何让它只调用该函数?当我以编程方式更改值时,它不应该调用该函数。

<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); 
    

【问题讨论】:

能否请您发布以编程方式更改下拉列表值的代码? dijit.byId("ddlBoundaryType").attr('value', 0); 【参考方案1】:

人们通常通过使用 priorityChange 标志来解决这个问题:

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

这将解决您的问题,除了值最初为 123 的微妙问题,您以编程方式将其设置为 456,然后用户将其设置回 123,在这种情况下不会有 onChange() 事件用户操作。

因此,您还可以这样做:

myWidget._lastValueReported=null;

【讨论】:

"set" 不是函数,我尝试了 dojo.byId、dijit.byId 和 this 来访问它,但没有一个将其作为可用函数。 _Widget.set() 是 1.5 中的新功能。在 1.5 之前,它被称为 attr()。请注意,此问题已在 bugs.dojotoolkit.org/ticket/10988 中修复,适用于 dojo 1.6,但由于暂时不会发布,请尝试上述解决方法。 谢谢,但不幸的是它不起作用(至少在 dojo 1.4.2 中)。将 .attr() 的第三个参数设置为 false 没有效果,它仍然调用 onchange 事件。此外,设置 _lastValueReported=null 会再次调用 onchange 事件... @BillKeese 很抱歉在这个老问题上打扰您。我想问你在dojo 1.10.4 中使用_setValueAttr 是否可以替代.set()。你知道_setValueAttr 是否会导致_lastValueReported 值出现问题吗?感谢您在此主题方面的专业知识。 @BillKeese 相关问题***.com/questions/44115583/…【参考方案2】:

我认为在这种情况下对您来说正确的解决方法是http://bugs.dojotoolkit.org/ticket/10594,因为它直接处理 dijit.form.Select。当然,有几种方法可以解决这个问题。

    升级道场:)。 继承 dijit.form.Select 并“修补”_updateSelection 函数。 扩展 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.

【讨论】:

#1 不是一个选项,因为 dojo 是 1.5 版,这将进入 1.6。我去看看#3,谢谢! 废话,我没注意到它是 1.6 的,嘘!【参考方案3】:

一个更简单的方法是,我想建议使用“_onChangeActive”标志,不建议使用它,因为它用于内部目的。但是,如果需要,我们可以使用它。 "_onChangeActive" 是 dojo Select 类型小部件中存在的标志,默认设置为 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”。

【讨论】:

以上是关于以编程方式更改值时触发 Dojo Select onChange 事件的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式更改 html 选择下拉菜单后,onchange 不会触发

以编程方式更改由标签值对对象填充的 Dojo Form Select 的选定选项

如何以编程方式更改 UISlider 拇指图像的大小

更改从商店加载选项的下拉 dojo 的字体大小

dijit.form.Select 不会以编程方式设置值

Angular2/material 2:当以编程方式更改值时,md-input-container 标签不会重置浮点数