2015-10-08 1 views
-1

J'ai la fonction suivantejavascript comment "réparer" une variable dans une fonction, via eval?

var label = function() { 
    return 'File: '+texts[t]; 
}; 

qui est attaché à Highcharts, indiqué ici http://api.highcharts.com/highcharts#plotOptions.pie.dataLabels.formatter

t a des valeurs disons de 1 à 10 et text[t] correspond à un texte différent. J'attache cette fonction à 10 highchart tooltips afin qu'il exécute la fonction avec un événement mouseOver.

La logique est que prévu tableau 1 présente l'étiquette text[1] apparaissant, le graphique 6 a text[6], etc.

Le problème est que toutes les cartes ont le text[10] apparaissant, puisque t a cette valeur lorsque la fonction est exécutée.

Comment puis-je résoudre ce problème? Est-ce un endroit pour eval() comme

var label = function() { 
    return 'File: '+eval(texts[t]); 
}; 

MISE À JOUR: en fonction des commentaires, en essayant

var label = function(t) { 
    return 'File: '+t+' '+texts[t]; 
}; 

ne fonctionne pas comme prévu, il imprime "Fichier: [object Object] undefined"

+0

vous n'avez pas besoin 'eval' pour cela, il suffit d'ajouter _t_ comme argument à la fonction et passer _t_ à lui de la boucle. ex: 'function (t)' et 'label (t)' – dandavis

+6

Le problème que vous décrivez est très courant lorsque la variable est accessible via une fermeture. Vous devez montrer la partie où 't' est initialisé et manipulé. – haim770

Répondre

2

Ceci est un problème de fermeture très commun:

Vous avez probablement t dans une boucle, juste envelopper le code qui fixe le gestionnaire dans une autre fonction:

// This will not work the way you might expect 
// The value of i is left at 10 because that is the last 
// time it is changed in the attacheHandlers1 scope held 
// but the closure in the anonymous function used as a callback 
// in setTimeout 
// 
function attachHandlers1(){ 
    for(var i = 0; i < 10 ; i++){ 
    setTimeout(function(){ 
     console.log("Version 1", i); 
    }, 100) 
    } 
} 

// This works because the value is closured in 
// attachHandlerImpl as 'x' with different values for 
// each invocation 
// 
function attachHandlers2(){ 
    for(var i = 0; i < 10 ; i++){ 
    attachHandlerImpl(i); 
    } 
} 

function attachHandlerImpl(x){ 
    setTimeout(function(){ 
     console.log("Version 2", x); 
    }, 100); 
} 

attachHandlers1(); 

attachHandlers2(); 

sortie Will:

Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 1 10 
Version 2 0 
Version 2 1 
Version 2 2 
Version 2 3 
Version 2 4 
Version 2 5 
Version 2 6 
Version 2 7 
Version 2 8 
Version 2 9 
+0

Bien que l'explication soit excellente, cela ne semble pas être compatible avec les hautes images car rien n'apparaît. Il semble que highcharts "protège" son code contre l'appel d'autres fonctions (la même chose arrive quand j'essaye eval) – Gerard

+0

En détail, le message est: TypeError: 'caller' et 'arguments' sont des propriétés de fonction restreintes et inaccessibles dans ce contexte . à Function.remoteFunction (: 3: 14) à Object.InjectedScript.callFunctionOn (: 750: 66) – Gerard

+0

Je vois que je dois implémenter cela en utilisant des variables préétablies dans les hautes images. L'esprit de la question est en tout cas très bien répondu dans votre message, donc je le donne comme la solution valable. Merci! – Gerard

0

Sans connaître le reste de vos détails de mise en œuvre, quelque chose comme ça pourrait fonctionner:

var texts = ['Text 1', 'Text 2', 'Text 3'] 
var label = function(idx) { 
    return "File: " + texts[idx]; 
}; 

label(2) renvoie « Fichier: Texte 3 »

+0

Question éditée pour ajouter plus de détails. J'ai essayé cette suggestion (égale à celle de Neal) mais cela ne fonctionne pas, je suppose en raison de l'implémentation de highcharts (?) – Gerard

+0

Veuillez montrer comment vous remplissez la valeur du tableau de textes. Votre exemple modifié donne l'impression que vous passez dans un objet, pas un index. –