在作用中使用范围变量作为参数,并使用其引用而不是值

时间:2015-11-16 07:19:25

标签: javascript angularjs angularjs-scope

我想在我的控制器中尝试使用泛型函数,我可以在我的视图中使用该函数来指示范围内的特定变量更改为特定值。

简化示例

控制器

$scope = {
    hair: {
        color: 'blue',
        length: '2cm'
    },
    mouth: 'wide',
    arms: [
        {
            fingers: 5,
            color: 'brown'
        },
        {
            fingers: 4,
            color: 'white'
        }
    ]
}

$scope.updateVariable = function(scopeVariable, value){
    scopeVariable = value;
}

视图

<a ng-click="updateVariable(hair.color, 'red');">red hair</a>
<a ng-click="updateVariable(hair.length, '5cm');">increase hair length</a>
<a ng-click="updateVariable(mouth, 'narrow');">narrow mouth</a>
<a ng-click="updateVariable(arms[0].fingers, 4);">4 fingers</a>

似乎只将变量的值传递给函数而不传递给引用。有没有办法让我从函数参数中获取对scope变量的引用而不是它的值?还能动态完成吗?通过这个我的意思是我需要将“路径”传递给该变量在范围内的位置。

我知道这可以通过独立的setter函数来完成(即:setMouth('narrow'))但是我们假设为了这个练习我们提前知道控制器中范围的结构但是只有在视图中,因此我们需要一个可以处理属性的泛型函数。

2 个答案:

答案 0 :(得分:1)

  

似乎只将变量的值传递给函数,而不传递给引用。

正确。

  

我有没有办法从函数参数中获取范围变量的引用而不是它的值?

不,JavaScript根本就没有(它被称为通过引用传递)。相反,您可以传递变量的名称,然后在您的函数中使用该名称:

<a ng-click="updateVariable('hair.color', 'red');">red hair</a>
<a ng-click="updateVariable('hair.length', '5cm');">increase hair length</a>
<a ng-click="updateVariable('mouth', 'narrow');">narrow mouth</a>
<a ng-click="updateVariable('arms[0].fingers', 4);">4 fingers</a>

然后应用this question and its answers中的技术从路径更新$scope。调整the answer by Alnitak中的函数使其成为一个setter:

Object.setByString = function(o, s, value) {
    s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
    s = s.replace(/^\./, '');           // strip a leading dot
    var a = s.split('.');
    for (var i = 0, n = a.length; i < n; ++i) {
        var k = a[i];
        if (k in o) {
            if (i == n - 1) {
                o[k] = value;
                return value;
            }
            o = o[k];
        } else {
            return value;
        }
    }
    return value;
};

然后

$scope.updateVariable = function(scopeVariablePath, value){
    Object.setByString($scope, scopeVariablePath, value);
};

答案 1 :(得分:1)

如果你传递物体,它们将是参考。

例如,不是将hair.color传回去,如果你将头发送回去,它会起作用。

那么也要更新?

在点击中设置它是一个选项。

ngclick =“hair.color ='red'”

你也可以传递属性。

带有变量的点表示法和括号表示法是相同的。

所以hair.color和hair [“color”]相同 - 后者可以是动态的。您可以传递属性名称并进行更新。