2010-07-12 5 views
10

J'ai une liste déroulante dojo (dijit) qui appelle une fonction js onChange. Je m'attendais à ce que cela appelle seulement la fonction onChange lorsque l'utilisateur change la valeur dans la liste déroulante, cependant, il appelle même la fonction onChange quand je change la valeur de la liste déroulante du code js. Comment est-ce que j'obtiens seulement pour appeler la fonction quand l'utilisateur change la valeur de liste déroulante? Il ne devrait pas appeler la fonction quand je change la valeur de la programmation.Dojo Sélectionnez le changement d'événement onChange lors de la modification programmée de la valeur

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

Merci, Justin

+0

Pourriez-vous s'il vous plaît poster le code qui modifie par programme la valeur du menu déroulant? – Abboq

+0

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

Répondre

0

Je pense que la solution appropriée dans ce cas, vous seriez http://bugs.dojotoolkit.org/ticket/10594, car il traite directement avec dijit.form.Select. Bien sûr, il existe plusieurs façons de résoudre ce problème.

  1. Mettre à niveau le dojo :).
  2. Héritez dijit.form.Sélectionnez et "corrigez" la fonction _updateSelection.
  3. Étendez dijit.form.Select et "patch" directement là.

Je vais renoncer à la première. Le second et la troisième méthode sont similaires, donc je vais simplement poster une solution simple en utilisant la troisième voie,

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

Notez que je n'ai pas écrit cette fonction, je heureusement plagié à partir du code source avec la dernière line, this._handleOnChange (this.value) supprimé.

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

# 1 n'est pas une option puisque dojo est la version 1.5 et cela se passe dans la version 1.6. Je vais jeter un oeil à # 3, merci! – Justin

+0

Blah, je n'ai pas remarqué que c'était pour 1,6, huez moi! –

11

Souvent, les gens résoudre ce problème en utilisant le drapeau priorityChange:

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

qui résoudra votre problème, sauf pour les questions subtiles où la valeur est à l'origine 123, vous définissez il est programmé à 456, puis l'utilisateur le rétablit à 123, auquel cas il n'y aura pas non plus d'événement onChange() pour l'action de l'utilisateur.

Pour cette raison, vous pouvez faire en plus:

myWidget._lastValueReported=null; 
+0

"set" n'est pas une fonction, j'ai essayé dojo.byId, dijit.byId, et ceci pour y accéder et aucun d'entre eux n'a cette fonction disponible. – Justin

+0

_Widget.set() est une nouvelle fonction dans 1.5. Pré-1.5, il s'appelait attr(). Notez que ce problème a été corrigé dans http://bugs.dojotoolkit.org/ticket/10988, pour dojo 1.6, mais puisque cela ne sera pas publié pendant un moment, essayez la solution de contournement ci-dessus. –

+0

Merci, mais malheureusement, cela ne fonctionne pas (au moins dans dojo 1.4.2.) Définir le troisième paramètre de .attr() sur false n'a aucun effet, il appelle toujours l'événement onchange. En outre, la définition de _lastValueReported = null appelle l'événement onchange une seconde fois ... – Justin

0

Une façon beaucoup plus simple est que, je voudrais suggérer le drapeau « _onChangeActive », ce qui est recommandé de ne pas utiliser, car il est sert des fins internes. Mais, si nécessaire, nous pourrions l'utiliser. "_onChangeActive" est un indicateur présent dans les widgets de type dojo Select, qui est défini par défaut sur true. Si cet indicateur est défini sur true, l'événement onChange est déclenché comme d'habitude. Mais, lorsqu'il est défini sur false, l'événement onChange n'est pas déclenché lorsque la valeur est modifiée par l'utilisateur ou programmée.

par exemple:

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 

Pas besoin d'hériter de la fonctionnalité existante pour ce dojo ou utiliser des indicateurs externes séparés. Le widget en a intégré un pour "_onChangeActive".

Questions connexes