2015-02-23 72 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