2010-02-04 6 views
1

J'ai une fonction javascript qui va quelque chose comme ceci:Faire de la variable de référence javascript une variable de valeur?

function doSomething(me) { 
     var isMeChecked = me.checked; 
     for (i=0;i<=10;i++) { 
      me.checked = !isMeChecked; 
      alert (me.checked); 
     } 
    } 

Je suppose que isMeChecked resterait constant après la première charge, mais il est apparemment une variable de référence à me.checked, et il change à chaque itération. Comment puis-je forcer isMeChecked pour obtenir la valeur me.checked lors de son chargement initial, et non la référence de me.checked?

Bon, pour le rendre plus clair, je suis l'édition de ce post pour afficher le code réel en cours d'utilisation qui expose le comportement indésirable:

Voici les fonctions javascript:

function CheckAll(me, gridViewId) { 
    var isMeChecked = (me.checked)?true:false; 
    alert('CheckAllFired_1'); 
    Parent = document.getElementById(gridViewId); 
    for (i = 0; i < Parent.rows.length; i++) { 
     alert('CheckAllFired_2_' + i.toString()); 
     var tr = Parent.rows[i]; 
     var td = tr.childNodes[0]; 
     var item = td.firstChild; 
     if (item.id != me.id && item.type == "checkbox") { 
      alert('CheckAllFired_3_' + i.toString() + '_' + me.checked + '_' + isMeChecked); 
      item.checked = !isMeChecked; 
      item.click(); 
     } 
    } 
} 
function CheckSelectAll(me, checkBoxHeaderId, gridViewId) { 
    alert('CheckSelectAllFired_1'); 
    if (!me.checked) { 
     alert('CheckSelectAllFired_2'); 
     document.getElementById(checkBoxHeaderId).checked = false; 
     return; 
    } 
    else { 
     alert('CheckSelectAllFired_3'); 
     document.getElementById(checkBoxHeaderId).checked = true; 
     Parent = document.getElementById(gridViewId); 
     for (i = 0; i < Parent.rows.length; i++) { 
      alert('CheckSelectAllFired_4_' + i.toString()); 
      var tr = Parent.rows[i]; 
      var td = tr.childNodes[0]; 
      var item = td.firstChild; 
      if (item.type == "checkbox") { 
       alert('CheckSelectAllFired_5_' + i.toString()); 
       if (!item.checked) { 
        alert('CheckSelectAllFired_6_' + i.toString()); 
        document.getElementById(checkBoxHeaderId).checked = false; 
        return; 
       } 
      } 
     } 
     return; 
    } 
} 

Je dispose d'un asp.net gridview. La première colonne est une colonne de cases à cocher, avec une case à cocher dans l'en-tête qui permet également de cocher "Sélectionner/Désélectionner tout" des autres cases de la colonne. La case à cocher dans l'en-tête a ses événements onclick mis à onclick="CheckAll(this, 'myGridViewClientID')"

Toutes les cases restantes dans la grille, ont leur événement onlick réglé sur onclick="CheckSelectAll(this, 'headerCheckBoxID', 'myGridViewClientID'"

Les deux headerCheckBoxID et myGridViewClientID sont fixés dans le codebehind lorsque le gridview est le rendu. L'idée est que lorsque la case à cocher de l'en-tête est cochée, toutes les autres cases à cocher sont activées, puis déclenchez leur événement click pour simuler un clic, puis déclenchez leurs actions surclic (qui impliquent des choses comme changer la couleur de leur rangée, en réglant la clé de données de la rangée dans un tableau SelectedValues ​​s'il est coché, etc.).

Cependant, je voulais également que les cases à cocher enfant aient le comportement suivant: 1) Si l'une d'entre elles n'est pas cochée, décochez la case "Sélectionner tout". 2) Si tous sont cochés, cochez la case "Sélectionner tout". Maintenant, parce que l'événement click de l'enfant a la possibilité de changer l'état vérifié de la headercheckbox, lorsque la boucle revient à l'événement "checkall", l'état de la headercheckbox est différent de ce qu'il était au début , et ainsi il finit seulement en cochant la case du premier enfant en essayant de faire tout sélectionner. En utilisant les alertes, j'ai pu voir que lorsque l'état checkedcheckbox est modifié dans la fonction CheckSelectAll, cette valeur est également modifiée pour la valeur "isMeChecked" dans la fonction CheckAll qui génère les fonctions CheckSelectAll.

Cela ressemble énormément à une variable de référence. Je ne sais pas comment l'empêcher de faire ça.

+0

Quelle est votre question? isMeChecked n'est pas une référence à moi-même, votre problème est ailleurs. – erikkallen

+0

Quelque chose ne va pas avec votre exemple de code. En supposant que je passe {checked: true} comme argument de doSomething, j'obtiens exactement la même valeur alertée à chaque fois. Aussi, qu'est-ce que me.checked! = IsMeChecked est supposé faire? C'est une déclaration inutile en ce moment, en supposant que check n'est pas un setter qui a des effets secondaires. –

+0

J'écrivais le code de la mémoire donc il y avait une faute de frappe. J'ai changé "me.checked! = IsMeChecked" à "me.checked =! IsMeChecked" qui est ce que j'ai réellement dans le vrai échantillon que je travaille avec. Dans le code réel, j'ai une case à cocher qui a un événement onclick qui appelle une fonction. La fonction définit l'état vérifié de plusieurs autres cases sur la page à la valeur opposée de la case d'origine, puis appelle l'événement onclick pour ces cases à cocher. La case à cocher de l'événement onclick pour les enfants modifie parfois la valeur cochée de la case parent, qui était alors en train de gâcher la boucle. –

Répondre

4

Pensez-y. Supposons x.checked = true. exécutez doSomething (x). Lorsque la fonction démarre, me.checked est true. Maintenant, regardez votre boucle for:

Passe 1: me.checked est vrai.donc isMeChecked est vrai. alors vous me définissez comme faux.

Passe 2: me.checked est faux. isMeChecked est toujours vrai, car vous ne le changez pas dans la boucle. Ainsi, je me suis de nouveau mis à false.

Passe 3: voir passer 2. ...

Lorsque les sorties de fonction, isMeChecked est vrai, et me.checked est faux. Tout ce que vous avez fait est mis à zéro 10 fois. Cela ne veut pas dire que isMeChecked soit une référence (parce que ce n'est pas le cas), mais seulement une erreur dans votre logique si vous attendiez des résultats différents.

+0

Eh bien, selon mes tests, IsMeChecked était en train de changer quand moi. vérifié a été changé. C'est pourquoi j'ai supposé que c'était une variable de référence. –

+0

Vous ne faisiez probablement pas le bon test. C'est simple à vérifier. Essayez ceci: 'var me = {vérifié: vrai}; var isMeChecked = me.checked; isMeChecked = false; alerte (me.checked)'. Vous verrez que me.checked est toujours vrai même si isMeChecked a été défini sur false. – glomad

-2

Vous pouvez faire var isMeChecked = me.checked?true:false;

En outre, me.checked != isMeChecked n'est pas la même chose que me.checked = !isMeChecked, ce qui est probablement ce que vous vouliez.

+0

ah oui, vous avez raison monsieur. Je le faisais de mémoire. C'est quelque chose sur lequel je travaillais au bureau et je n'avais pas le code devant moi. En plus, je ne suis pas un gourou javascript par tous les moyens, ce qui ajoute aux erreurs. =) Je vais essayer votre suggestion première chose le matin. Merci! (correction de l'erreur dans le message d'origine) –

+4

me.checked? True: false est un non-sens – erikkallen

+0

Is not var isMeChecked = (me.checked)? True; false; un exemple de "l'opérateur conditionnel" comme en C#? –

0

Sauf si je suis fou, il n'y a pas de référence à un booléen en javascript. Ils sont toujours passés en valeur. Pouvez-vous coller un exemple complet de code que nous pouvons exécuter sans remplir aucun espace?

0

Votre boucle est juste cassé - Lire les commentaires

// doSomething({checked:true}); 
function doSomething(me) { 
    // isMeChecked = true; 
    var isMeChecked = me.checked; 
    for (i=0;i<=10;i++) { 
     // me.checked = false ... always... 
     me.checked = !isMeChecked; 
     alert (me.checked); 
    } 
} 
Questions connexes