97

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),但是在赋值时如何做呢?

4

8 回答 8

175

我找到的解决方案是使用$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
于 2013-09-18T14:49:02.700 回答
20

以 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 的情况下对其进行了测试。没有它也能正常工作!

于 2015-02-16T02:01:42.867 回答
13

从结果创建动态角度变量

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

附言。不要忘记将 $parse 属性传递到控制器的函数中

于 2015-02-11T17:21:11.710 回答
5

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

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

https://lodash.com/docs#set

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

于 2015-09-23T09:19:33.303 回答
4

只是为了添加到已经给出的答案中,以下内容对我有用:

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];
}
于 2016-12-06T06:56:48.737 回答
3

请记住:这只是一个 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']);

或者多花点力气。

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
})
于 2014-06-11T19:14:53.343 回答
0

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

在角度范围内设置值。

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

从角度范围获取值。

_.get($scope, 'life.meaning')
于 2018-10-29T11:01:00.923 回答
-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;
    });
}

现在 {{subjects}} 将返回一个数据主体名称数组,在我的示例中,$scope 中将有 {{jobs}}、{{customers}}、{{staff}} 等的范围属性。工作,$scope.customers,$scope.staff

于 2013-11-29T01:37:56.600 回答