99 votes

Définition des variables de portée dynamique dans AngularJs - portée.<some_string>

J'ai une chaîne que j'ai obtenue d'un routeParam ou d'un attribut de directive ou autre chose, et je veux créer une variable sur la portée basée sur cela. Donc :

$scope. = "quelque chose".

Cependant, si la chaîne contient un ou plusieurs points, je veux la diviser et en fait "descendre" dans la portée. Donc 'foo.bar' devrait devenir $scope.foo.bar. Cela signifie que la version simple ne fonctionnera pas !

// Cela ne fonctionnera pas car l'assignation de variables de cette manière ne "descendra" pas
// Elle attribuera à des variables nommées exactement la chaîne complète, points et tout.
var the_string = 'vie.sens';
$scope[the_string] = 42;
console.log($scope.vie.sens);  // <-- Non ! Ceci est indéfini.
console.log($scope['vie.sens']);  // <-- C'est par ici à la place !

Lors de la lecture d'une variable basée sur une chaîne, vous pouvez obtenir ce comportement en faisant $scope.$eval(the_string), mais comment le faire lors de l'attribution d'une valeur ?

176voto

Erik Honn Points 1839

La solution que j'ai trouvée est d'utiliser $parse.

"Convertit une expression Angular en une fonction."

Si quelqu'un en a une meilleure, veuillez ajouter une nouvelle réponse à la question !

Voici l'exemple :

var the_string = 'life.meaning';

// Obtenir le modèle
var model = $parse(the_string);

// Assigner une valeur à celui-ci
model.assign($scope, 42);

// Appliquez-le à la portée
// $scope.$apply(); <- Selon les commentaires, ce n'est plus nécessaire

console.log($scope.life.meaning);  // enregistre 42

20voto

Andrew Points 31

En utilisant la réponse d'Erik, comme point de départ. J'ai trouvé une solution plus simple qui a fonctionné pour moi.

Dans ma fonction ng-click, j'ai :

var the_string = 'lifeMeaning';
if ($scope[the_string] === undefined) {
   //Valide dans mon application pour la première utilisation
   $scope[the_string] = true;
} else {
   $scope[the_string] = !$scope[the_string];
}
//$scope.$apply

Je l'ai testé avec et sans $scope.$apply. Fonctionne correctement sans cela!

13voto

Demodave Points 3233

Créer des variables angulaires dynamiques à partir des résultats

angular.forEach(results, function (value, key) {          
  if (key != null) {                       
    $parse(key).assign($scope, value);                                
  }          
});

ps. n'oubliez pas de passer l'attribut $parse dans la fonction de votre contrôleur

5voto

NorthernStar Points 51

Si vous êtes d'accord pour utiliser Lodash, vous pouvez faire ce que vous voulez en une seule ligne en utilisant _.set() :

_.set(object, path, value) Définit la valeur de la propriété de chemin sur l'objet. Si une partie du chemin n'existe pas, elle est créée.

https://lodash.com/docs#set

Donc, votre exemple serait simplement : _.set($scope, the_string, something);

4voto

Riaz Points 104

Juste pour ajouter aux réponses déjà données, ce qui suit a fonctionné pour moi:

HTML:

$index est l'index de la boucle.

Javascript (où valeur est le paramètre transmis à la fonction et ce sera la valeur de $index, l'index de la boucle actuelle):

var variable = "val"+valeur;
if ($scope[variable] === undefined)
{
    $scope[variable] = true;
}else {
    $scope[variable] = !$scope[variable];
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X