2010-07-12 8 views
10

Tengo un menú desplegable de selección dojo (dijit) que llama a una función js en Cambio. Esperaba que esto solo llamara a la función onChange cuando el usuario cambia el valor en el menú desplegable, sin embargo, incluso llama a la función onChange cuando programáticamente cambio el valor del menú desplegable del código js. ¿Cómo hago para llamar solo a la función cuando el usuario cambia el valor desplegable? No debería invocar la función cuando modifique programáticamente el valor.Dojo Seleccione la activación del evento onChange al cambiar el valor programáticamente

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

Gracias, Justin

+0

¿Podría publicar el código que programáticamente cambia el valor de la lista desplegable? – Abboq

+0

dijit.byId ("ddlBoundaryType"). Attr ('valor', 0); – Justin

Respuesta

0

creo que la solución adecuada en este caso para usted sería http://bugs.dojotoolkit.org/ticket/10594, ya que trata directamente con dijit.form.Select. Por supuesto, hay algunas formas de arreglar esto.

  1. Actualización dojo :).
  2. Heredar dijit.form.Select y "parchear" la función _updateSelection.
  3. Extienda dijit.form.Seleccione y "parche" directamente allí.

Voy a renunciar a la primera. El segundo y el tercer método son similares, por lo que sólo voy a publicar una solución simple uso de la tercera vía,

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

Tenga en cuenta que no he escrito esta función, con mucho gusto plagiado desde el código fuente de la última line, this._handleOnChange (this.value) eliminado.

myWidget.attr('value', newValue, false) // should now work without firing onChange. 
+0

# 1 no es una opción, ya que dojo es la versión 1.5 y está yendo a 1.6. Echaré un vistazo al # 3, ¡gracias! – Justin

+0

Blah, no me di cuenta de que era para 1.6, abucheo! –

11

A menudo la gente a resolver esto mediante el uso de la bandera priorityChange:

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

que va a resolver su problema excepto por cuestiones sutiles donde el valor es inicialmente 123, se establece programáticamente a 456, y luego el usuario lo establece de nuevo a 123, en cuyo caso tampoco habrá un evento onChange() para la acción del usuario.

Por eso se puede hacer, además:

myWidget._lastValueReported=null; 
+0

"set" no es una función, probé dojo.byId, dijit.byId, y esto para acceder a él y ninguno de ellos tiene eso como una función disponible. – Justin

+0

_Widget.set() es una nueva función en 1.5. Pre-1.5 se llamaba attr(). Tenga en cuenta que este problema se ha resuelto en http://bugs.dojotoolkit.org/ticket/10988, para dojo 1.6, pero dado que no se lanzará por un tiempo, intente la solución anterior. –

+0

Gracias, pero desafortunadamente no funciona (al menos en dojo 1.4.2.) Establecer el tercer parámetro de .attr() en falso no tuvo ningún efecto, todavía llama al evento onchange. Además, establecer _lastValueReported = null llama al evento onchange por segunda vez ... – Justin

0

Una manera mucho más simple es que, me gustaría sugerir la bandera "_onChangeActive", que no se recomienda su uso, ya que es sirve al propósito interno. Pero, si es necesario, podríamos usarlo. "_onChangeActive" es una marca presente en dojo Seleccione tipo de widgets, que está configurado por defecto en verdadero. Si este indicador se establece en verdadero, el evento onChange se desencadena de la forma habitual. Pero, cuando se establece en falso, el evento onChange no se desencadena, cuando el valor es cambiado por el usuario o programáticamente.

por ejemplo:

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 

No hay necesidad de heredar la funcionalidad existente para este dojo o usar banderas exteriores separadas. El widget tiene uno incorporado para esto - "_onChangeActive".

Cuestiones relacionadas