2015-02-23 79 views
3

在Angular中,一个关键特性是双向绑定,它始终保持模型始终处于最新状态。但是,我有一种情况,即具有本质上属于某个模型的依赖属性。我的问题是关于如何实现它。我可以在视图中插入一个表达式来显示依赖于模型元素的计算,但我希望将该表达式指定为模型中的一个字段,以便其他表达式可以使用该结果并更新一切。Angular模型中的依赖属性

一个简单的例子可能具有字段一个b,并在模型中Ç,与C = A * B。这有可能把{{a * b}}到视图,但是,我宁愿有一个字段ç,这样我可以在其他表达式中引用Ç和简单的使用{{c}}在视图中,我需要它显示,与Ç更新每当ab被更新。

我想你可以把手表放在一个b,并重新计算Ç,但它似乎是机器已在角某处有一个自动的完成,因为它适用于在视图中的表达式。如果我提前不知道表达式(我不会),我需要解析表达式c来拉出变量,并在所有表上设置手表......当然,对于Angular,一个更好的方法。

是否可以像将角度表达式放入模型一样?

我知道这里存在危险 - 你可以创建一个自引用循环,但是这可以被检测到,从而可以抛出错误。

+4

控制器:'$ scope.calculatedVariable =函数(){返回A * B}'查看:'{{ctrl.calculatedVariable()}}' – 2015-02-23 04:08:47

回答

1

Knockout具有computeableObservable的概念,但angular没有这种不同的东西。不过你可以做下面的事情。当a改变时它会自动改变c的值。看下面的代码片段。

var app = angular.module('plunker', []); 
 

 
app.controller('MainCtrl', function($scope) { 
 
    $scope.name = 'World'; 
 
    $scope.a=5; 
 
    $scope.b=10; 
 
    $scope.c = function(){return $scope.a*$scope.b} 
 
    $scope.changea = function(){$scope.a = 25} 
 
});
<!DOCTYPE html> 
 
<html ng-app="plunker"> 
 

 
    <head> 
 
    <meta charset="utf-8" /> 
 
    <title>AngularJS Plunker</title> 
 
    <script>document.write('<base href="' + document.location + '" />');</script> 
 
    <link rel="stylesheet" href="style.css" /> 
 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.13/angular.js" data-semver="1.3.13"></script> 
 
    <script src="app.js"></script> 
 
    </head> 
 

 
    <body ng-controller="MainCtrl"> 
 
    <p>Hello {{name}}!</p> 
 
    {{c()}} 
 
    <input type="button" value="change a value to 25" ng-click="changea()" /> 
 
    a = {{a}} 
 
    </body> 
 

 
</html>

1

凯尔和Jenish提供了很好的答案,可能是在许多情况下,适当的,但仍然在

  1. 一个微妙的差异,您需要使用括号每当财产被引用;和
  2. 只有在需要时才需要计算值,而只有在其相关性发生变化时才会计算值,这大概会导致效率损失。

搜索“计算属性”后(感谢Jenish - 这就是我需要的术语),我发现它可以消除括号(thanks to this article),但我还没有发现保存值,只有一个解决方案在需要时更新它。

可以在javascript中为对象添加属性,并且只定义一个getter,它本身很好,但是因为它适用于Angular系统,所以更大。

请注意,在下面的代码片段中,'vars'属性仅用于提供数学函数的上下文以及我们在此特定示例中向用户公开的变量。这种一般方法只有Object.defineProperty(...)是必不可少的。

var app = angular.module('tester', []); 
 

 
app.controller('VariablesCtrl', function($scope) { 
 

 
    // Init context with Math for access to functions 
 
    $scope.vars = window.Math; 
 

 
    // Init variables 
 
    $scope.vars.a = 2; 
 
    $scope.vars.b = 3; 
 
    $scope.vars.c_expr = 'a * b'; 
 
    $scope.vars.d_expr = 'pow(c , 2) + 10'; 
 

 
    // Add dependent property to $scope for c and d, based on user input expressions 
 
    Object.defineProperty($scope.vars, 'c', { 
 
    get: function() { 
 
     return $scope.$eval($scope.vars.c_expr, $scope.vars); 
 
    } 
 
    }); 
 

 
    Object.defineProperty($scope.vars, 'd', { 
 
    get: function() { 
 
     return $scope.$eval($scope.vars.d_expr, $scope.vars); 
 
    } 
 
    }); 
 

 
});
<!DOCTYPE html> 
 
<html xmlns="http://www.w3.org/1999/xhtml" ng-app="tester"> 
 

 
<head> 
 
    <title>Angular Computed Properties</title> 
 
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> 
 
</head> 
 

 
<body> 
 
    <div ng-controller="VariablesCtrl"> 
 
    <p> 
 
     a: 
 
     <input type="number" ng-model="vars.a" /> 
 
    </p> 
 
    <p> 
 
     b: 
 
     <input type="number" ng-model="vars.b" /> 
 
    </p> 
 
    <p> 
 
     c (an expression): 
 
     <input type="text" ng-model="vars.c_expr" /> 
 
    </p> 
 
    <p> 
 
     c: {{vars.c}} 
 
    </p> 
 
    <p> 
 
     d (an expression): 
 
     <input type="text" ng-model="vars.d_expr" /> 
 
    </p> 
 
    <p> 
 
     d: {{vars.d}} 
 
    </p> 
 
    </div> 
 
    <script data-require="[email protected]" src="https://code.angularjs.org/1.3.13/angular.js" data-semver="1.3.13"></script> 
 
</body> 
 

 
</html>

1

有,我相信是真的角方式第三种方式。

当您的范围变量发生变化时,您可以对$ scope成员使用$ watch来获取回调。在最新的角度版本中,您可以在一个命令中查看一组变量。

所以这会是这样的

$scope.$watch('a', function(newValue, oldValue) { 
    $scope.c= newValue + $scope.b; 
}); 
$scope.$watch('b', function(newValue, oldValue) { 
    $scope.c= newValue + $scope.a; 
}); 
+0

有一种基于函数或字符串表达式来计算要监视哪些变量的方法? Angular似乎能够为视图表达式做到这一点,但它对我来说并不明显。即使当变量间接依赖时,Vire表达式(双卷曲)也会更新,例如在Jenish的答案中,c()是因变量的函数。一旦将c()放入视图中的表达式中,它将在该函数中的变量更新时更新。 Angular如何知道它需要关心的c()内部的变量? – 2015-02-23 14:14:24

+0

监视表达式是一个字符串,其范围内名称为变量(在我的示例中为'a'和'b'),所以如果您可以从表达式中提取范围变量,那么您可以通过编程方式创建手表。 Angular在内部使用$ watch来更新模板,所以如果以间接方式更新它并不重要。它比较任何事件发生后的范围值,并调用手表,直到它们停止生产更改以调用其他手表 – SeriousDron 2015-02-23 15:25:32