在AngularJs中设置动态范围变量 - 范围。<some_string> </some_string>

时间:2013-09-18 14:49:03

标签: 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)来获取此行为,但在分配值时如何执行此操作?

8 个答案:

答案 0 :(得分:169)

我找到的解决方案是使用$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

答案 1 :(得分:18)

以Erik的答案为出发点。我找到了一个对我有用的简单解决方案。

在我的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。没有它正确工作!

答案 2 :(得分:13)

从结果中创建动态角度变量

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

PS。不要忘记将$ parse属性传递给控制器​​的函数

答案 3 :(得分:5)

如果你可以使用Lodash,你可以使用_.set()在一行中做你想做的事情:

  

_。set(object,path,value)设置对象上path的属性值。如果路径的一部分不存在,则创建它。

https://lodash.com/docs#set

所以你的例子就是:_.set($scope, the_string, something);

答案 4 :(得分:3)

只是添加到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];
}

答案 5 :(得分:2)

请记住:这只是一个JavaScript的东西,与Angular JS无关。所以不要对神奇的'$'符号感到困惑;)

主要问题是这是一个分层结构。

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

这是未定义的,因为“$ scope.life”不存在,但上述术语想解决“含义”。

解决方案应该是

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

或者更多的efford。

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 :(得分:0)

如果您正在使用下面的Lodash库,则可以在角度范围内设置动态变量。

  

在角度范围内设置值。

_.set($scope, the_string, 'life.meaning')
  

要从角度范围中获取值。

_.get($scope, 'life.meaning')

答案 7 :(得分:-1)

如果你试图做我想象你想做的事情,那么你只需要将范围看作普通的JS对象。

这是我用于JSON数据阵列的API成功响应......

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

现在{{臣民}}将返回一组数据主题名称,在我的示例中,{{jobs}},{{customers}},{{staff}}等的范围属性将来自$ scope.jobs,$ scope.customers,$ scope.staff