Establecer variables de ámbito dynamic en AngularJs – scope.

Tengo una cadena que obtuve de un routeParam o un atributo de directiva o lo que sea, y quiero crear una variable en el scope en función de esto. Asi que:

 $scope. = "something". 

Sin embargo, si la cadena contiene uno o más puntos, quiero dividirlo y realmente “profundizar” en el scope. Entonces 'foo.bar' debería convertirse en $scope.foo.bar . Esto significa que la versión simple no funcionará.

 // This will not work as assigning variables like this will not "drill down" // It will assign to a variables named the exact string, dots and all. var the_string = 'life.meaning'; $scope[the_string] = 42; console.log($scope.life.meaning); // <-- Nope! This is undefined. console.log($scope['life.meaning']); // <-- It is in here instead! 

Al leer una variable basada en una cadena, puede obtener este comportamiento haciendo $scope.$eval(the_string) , pero ¿cómo hacerlo al asignar un valor?

La solución que he encontrado es usar $ parse .

“Convierte la expresión angular en una función”.

Si alguien tiene uno mejor, ¡por favor agregue una nueva respuesta a la pregunta!

Aquí está el ejemplo:

 var the_string = 'life.meaning'; // Get the model var model = $parse(the_string); // Assigns a value to it model.assign($scope, 42); // Apply it to the scope // $scope.$apply(); < - According to comments, this is no longer needed console.log($scope.life.meaning); // logs 42 

Usando la respuesta de Erik, como punto de partida. Encontré una solución más simple que funcionó para mí.

En mi función ng-click tengo:

 var the_string = 'lifeMeaning'; if ($scope[the_string] === undefined) { //Valid in my application for first usage $scope[the_string] = true; } else { $scope[the_string] = !$scope[the_string]; } //$scope.$apply 

Lo he probado con y sin $ scope. $ Apply. Funciona correctamente sin eso!

Crear variables angulares dinámicas a partir de resultados

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

PD. no olvide pasar el atributo $ parse en la función de su controlador

Si estás de acuerdo con el uso de Lodash, puedes hacer lo que deseas en una línea usando _.set ():

_.set (object, path, value) Establece el valor de la propiedad de la ruta en el objeto. Si una porción de ruta no existe, se crea.

https://lodash.com/docs#set

Entonces su ejemplo sería simplemente: _.set($scope, the_string, something);

Solo para agregar respuestas proporcionadas, lo siguiente funcionó para mí:

HTML:

 

Donde $index es el índice de ciclo.

Javascript (donde value es el parámetro pasado a la función y será el valor de $index , current loop index):

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

Tenga en cuenta que esto es solo un JavaScript y no tiene nada que ver con Angular JS. Así que no te confundas con el mágico signo ‘$’;)

El problema principal es que esta es una estructura jerárquica.

 console.log($scope.life.meaning); // < -- Nope! This is undefined. => abc 

Esto no está definido porque “$ scope.life” no existe, pero el término anterior quiere resolver el “significado”.

Una solución debe ser

 var the_string = 'lifeMeaning'; $scope[the_string] = 42; console.log($scope.lifeMeaning); console.log($scope['lifeMeaning']); 

o con un poco más de esfuerzo.

 var the_string_level_one = 'life'; var the_string_level_two = the_string_level_one + '.meaning'; $scope[the_string_level_two ] = 42; console.log($scope.life.meaning); console.log($scope['the_string_level_two ']); 

Dado que puede acceder a un objeto estructural con

 var a = {}; ab = "ab"; console.log(ab === a['b']); 

Hay varios buenos tutoriales sobre esto que te guiarán bien a través de la diversión con JavaScript.

Hay algo sobre el

 $scope.$apply(); do...somthing...bla...bla 

Vaya y busque en la web ‘angular $ apply’ y encontrará información sobre la función $ apply. Y debe usar sabiamente más de esta manera (si ya no tiene una fase $ apply).

 $scope.$apply(function (){ do...somthing...bla...bla }) 

Si estabas tratando de hacer lo que imagino que estabas tratando de hacer, entonces solo tienes que tratar el scope como un objeto JS normal.

Esto es lo que uso para una respuesta exitosa API para la matriz de datos JSON …

 function(data){ $scope.subjects = []; $.each(data, function(i,subject){ //Store array of data types $scope.subjects.push(subject.name); //Split data in to arrays $scope[subject.name] = subject.data; }); } 

Ahora {{subject}} devolverá una matriz de nombres de sujetos de datos, y en mi ejemplo, habría un atributo de scope para {{jobs}}, {{customers}}, {{staff}}, etc. desde $ scope. trabajos, $ scope.customers, $ scope.staff