Установка динамических переменных области в AngularJs-scope.
у меня есть строка, которую я получил от routeParam
или атрибут директивы или что-то еще, и я хочу создать переменную в области, основанной на этом. Итак:
$scope.<the_string> = "something".
однако, если строка содержит одну или несколько точек, я хочу разделить ее и фактически "развернуть" в область. Так что 'foo.bar'
должны стать $scope.foo.bar
. Это означает, что простая версия не будет работать!
// 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!
при чтении переменной на основе строки вы можете получить это поведение, выполнив $scope.$eval(the_string)
, но как это сделать при присвоении значения?
7 ответов:
решение, которое я нашел, это использовать $parse.
"преобразует Угловое выражение в функцию."
Если у кого есть лучше, пожалуйста, добавьте новый ответ на вопрос!
вот пример:
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
используя ответ Эрика, как отправную точку. Я нашел более простое решение, которое работает для меня.
в моей функции ng-click у меня есть:
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
Я проверил его с и без $ scope.$применять. Работает корректно и без него!
создание динамических угловых переменных с результатами
angular.forEach(results, function (value, key) { if (key != null) { $parse(key).assign($scope, value); } });
ps. не забудьте передать атрибут $parse в функцию вашего контроллера
Если вы в порядке с использованием Lodash, вы можете сделать то, что вы хотели в одной строке с помощью _.set ():
_.set (object, path, value)задает значение свойства path для объекта. Если часть пути не существует, она создается.
Так что ваш пример будет просто:
_.set($scope, the_string, something);
просто чтобы добавить в alread данные ответы, для меня сработало следующее:
HTML:
<div id="div{{$index+1}}" data-ng-show="val{{$index}}">
здесь
$index
- это индекс цикла.Javascript (где
value
является переданным параметром функции, и это будет значение$index
, текущий индекс цикла):var variable = "val"+value; if ($scope[variable] === undefined) { $scope[variable] = true; }else { $scope[variable] = !$scope[variable]; }
пожалуйста, имейте в виду: это просто JavaScript вещь и не имеет ничего общего с угловой JS. Так что не путайте с магическим знаком"$";)
главная проблема заключается в том, что это иерархическая структура.
console.log($scope.life.meaning); // <-- Nope! This is undefined. => a.b.c
это не определено, потому что " $scope.жизнь " не существует, но термин выше хочет решить "смысл".
решение должно быть
var the_string = 'lifeMeaning'; $scope[the_string] = 42; console.log($scope.lifeMeaning); console.log($scope['lifeMeaning']);
или с немного большим усилием.
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 ']);
так как вы можете доступ к структурному объекту с помощью
var a = {}; a.b = "ab"; console.log(a.b === a['b']);
есть несколько хороших учебников об этом, которые помогут вам хорошо провести время с помощью JavaScript.
есть что-то о
$scope.$apply(); do...somthing...bla...bla
перейдите и найдите в интернете "angular $apply", и вы найдете информацию о функции $apply. И вы должны использовать разумно больше таким образом (если вы еще не с фазой $apply).
$scope.$apply(function (){ do...somthing...bla...bla })
Если вы пытались сделать то, что я предполагаю, что вы пытались сделать, то вам нужно только рассматривать область как обычный объект JS.
Это то, что я использую для ответа API success для массива данных 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; }); }
теперь {{subjects}} вернет массив имен субъектов данных, и в моем примере будет атрибут scope для {{jobs}}, {{customers}}, {{staff}} и т. д. из $scope.рабочих мест, $объем.клиенты, $объем.персонал