Установка динамических переменных области в 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 91

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 для объекта. Если часть пути не существует, она создается.

https://lodash.com/docs#set

Так что ваш пример будет просто: _.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.рабочих мест, $объем.клиенты, $объем.персонал