Настройка переменных динамической области в AngularJs - область. <Some_string>

У меня есть строка, полученная из атрибута 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), но как это сделать при назначении значения?

Ответ 1

Решение, которое я нашел, заключается в использовании $parse.

"Преобразует выражение Angular в функцию."

Если у кого-то есть лучший, добавьте новый ответ на вопрос!

Вот пример:

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

Ответ 2

Использование ответа Эрика в качестве отправной точки. Я нашел более простое решение, которое сработало для меня.

В моей функции 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. $apply. Работает без него!

Ответ 3

Создать динамические переменные angular из результатов

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

пс. не забудьте передать атрибут $parse в функцию вашего контроллера.

Ответ 4

Если вам нравится использовать Lodash, вы можете сделать то, что хотите в одной строке, используя _.set():

_. set (object, path, value) Устанавливает значение свойства пути для объекта. Если часть пути не существует, она создана.

https://lodash.com/docs#set

Итак, ваш пример будет просто: _.set($scope, the_string, something);

Ответ 5

Пожалуйста, имейте в виду: это всего лишь вещь JavaScript и не имеет ничего общего с Angular JS. Так что не путайтесь с магическим знаком "$";)

Основная проблема заключается в том, что это иерархическая структура.

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

Это undefined, потому что "$ scope.life" не существует, но термин выше хочет решить "значение".

Решение должно быть

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
})

Ответ 6

Чтобы добавить в 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];
}

Ответ 7

Если вы пытались сделать то, что, я думаю, вы пытались сделать, тогда вам нужно только обрабатывать область видимости как обычный объект JS.

Это то, что я использую для ответа на успех API для массива данных 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;
    });
}

Теперь {{subject}} вернет массив имен объектов данных, и в моем примере будет атрибут scope для {{jobs}}, {{customers}}, {{staff}} и ​​т.д. из $scope.jobs, $scope.customers, $scope.staff