以编程方式更改值时触发 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 不会触发