Reputation: 787
I have a repeater using ng-repeat which binds to a array of dynamic/ run time computed values. ( i.e, my array contains fields like Brokerage: ($scope.BuyValue() + $scope.SellValue())* 0.5/100 ).
When i change the value in the input box which has a ng-model , field Broker.Brokerage inside the repeater is not getting refreshed. But i am able to update/bind the fields outside the repeater properly.
<body ng-controller="BrokerController">
<div>
<div>
Buy Price <input type="textbox" ng-model="BuyPrice"/><br/>
Sell Price <input type="textbox" ng-model="SellPrice"/><br/>
Quantity <input type="textbox" ng-model="Quantity"/><br/>
Buy Value {{ BuyValue() }} <br/>
Sell Value {{ SellValue() }} <br/>
Profit {{ Profit() }} <br/><br/><br/>
<h4>Brokers</h4>
<div ng-repeat='Broker in Brokers'>
Broker Name : <b>{{Broker.BrokerName}}</b>
Brokerage Amount : <i>{{Broker.Brokerage}}</i> ({{Broker.BrokerageDetail}})
<br/>
</div>
</div>
</div>
<script id="angularjs" src="js/lib/angular/angular.js"></script>
<script>
var App = angular.module('ChooseYourBroker', []);
App.controller("BrokerController", ['$scope', function ($scope) {
$scope.BuyPrice = 10;
$scope.SellPrice = 20;
$scope.Quantity = 100;
$scope.BuyValue = function(){ return ( $scope.BuyPrice * $scope.Quantity )};
$scope.SellValue = function(){ return ( $scope.SellPrice * $scope.Quantity )};
$scope.Profit = function(){ return ( $scope.SellValue() - $scope.BuyValue() )};
$scope.Brokers = [
{
BrokerName: 'Broker one',
BrokerageDetail :'0.5% value of Sell Value',
Brokerage: $scope.SellValue() * 0.5/100
},
{
BrokerName: 'Broker two',
BrokerageDetail :'2% value of Sell Value',
Brokerage: $scope.SellValue() * 2/100
},
{
BrokerName: 'Broker three',
BrokerageDetail :'1% value of Sell Value',
Brokerage: $scope.SellValue() * 1/100
},
{
BrokerName: 'Broker Four',
BrokerageDetail :'0.5 % value of Buy Value and Sell Value',
Brokerage: ($scope.BuyValue() + $scope.SellValue())* 0.5/100
}];
}]);
</script>
Upvotes: 2
Views: 5543
Reputation: 520
So angularJS ng-model doesn't update primitives. If you want it to automatically update it would be better to do something like
$scope.share={};
$scope.share.BuyPrice = 10;
$scope.share.SellPrice = 20;
$scope.share.Quantity = 100;
and change
Buy Price <input type="textbox" ng-model="BuyPrice"/><br/>
Sell Price <input type="textbox" ng-model="SellPrice"/><br/>
Quantity <input type="textbox" ng-model="Quantity"/><br/>
to
Buy Price <input type="textbox" ng-model="share.BuyPrice"/><br/>
Sell Price <input type="textbox" ng-model="share.SellPrice"/><br/>
Quantity <input type="textbox" ng-model="share.Quantity"/><br/>
That way the values of share will automatically update without needing to use $watch or setters and getters. However it will not automatically call function(){ return ( $scope.SellValue() - $scope.BuyValue() )}; again
To do this I would do
Buy Price <input type="textbox" ng-model="share.BuyPrice" ng-change="updatePrices()"/><br/>
Sell Price <input type="textbox" ng-model="share.SellPrice" ng-change="updatePrices()"/><br/>
Quantity <input type="textbox" ng-model="share.Quantity" ng-change="updatePrices()"/><br/>
and
$scope.updatePrices=function(){
$scope.share.BuyValue = function(){ return ( $scope.share.BuyPrice * $scope.share.Quantity )};
$scope.share.SellValue = function(){ return ( $scope.share.SellPrice * $scope.share.Quantity )};
$scope.share.Profit = function(){ return ( $scope.share.SellValue() - $scope.share.BuyValue() )};
}
Upvotes: 0
Reputation: 35478
This is because Brokerage
is calculated once, when it is run. Since you did not make a getter function of it or did not run a watcher, it will not be updated. You have two options:
JS:
{
BrokerName: 'Broker Four',
BrokerageDetail :'0.5 % value of Buy Value and Sell Value',
GetBrokerage: function () { return ($scope.BuyValue() + $scope.SellValue())* 0.5/100;}
}
HTML:
<span ng-bind="Broker.GetBrokerage()"></span>
BuyValue
and SellValue
, and update Brokers
.JS:
$scope.$watch("BuyValue()", function () { /*update all the brokers*/ });
$scope.$watch("SellValue()", function () { /*update all the brokers*/ });
Upvotes: 4
Reputation: 63069
You need to set a $watch
on SellValue()
in order to be notified whenever the returned value changes:
$scope.$watch('SellValue()',function(newValue){
for(var i=0;i<$scope.Brokers.length;i++){
$scope.Brokers[i].Brokerage = ... * newValue; // Calculate the Brokerage
}
});
Explanation: The view can bind to model values through the scope. The Brokers
object is not a view element and so is not bound to anything. A $watch
is needed when the model wants to be notified in changes to other parts of the model. Otherwise, your Brokerage
property gets calculated only once during the controller's initial run phase.
Here is a fiddle where I've created a BrokerageRate
to compute the new Brokerage any time the SellValue()
changes.
Broker Four
will need a little more work in that there will need to be another watch on BuyValue()
as that Brokerage
property needs to be notified of changes to both values.
Upvotes: 3