2

Here is a current example of my problem: http://jsfiddle.net/JSce5/3/

I'm trying to accept numbers from input fields in the view, then pass the values to the controller, run a calculation, then return the new value as a new variable name to the view. I'm new to AngularJS and I'm still trying to figure out how to do the basics here. Any help or insight would be very appreciated. Thanks!

<div ng-controller="MainCtrl">

Amount: <input type="number" ng-init="amountone=28" ng-model="amountone"> Value: <input type="number" ng-init="valueone=300" ng-model="valueone">
<br />
Amount: <input type="number" ng-init="amounttwo=3.5" ng-model="amounttwo"> Value: <input type="number" ng-init="valuetwo=50" ng-model="valuetwo">
<br /><br />
=========================
<br /><br />
Test ratio: {{ amountone }}/{{ amounttwo}} = {{ ratioone }}<br />
Test ratio: {{ amounttwo }}/{{ amountone}} = {{ ratiotwo }}<br />
</div>

====

'use strict';

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

app.controller('MainCtrl', function ($scope) {
    console.log($scope);
    $scope.ratioone = $scope.amountone / $scope.amounttwo;
    $scope.ratiotwo = $scope.amounttwo / $scope.amountone;

});

2 Answers 2

2

Instead of using a function to do your calculation as @m59 suggestions, it may be more efficient to simply use watchers to update your calculations when things change:

'use strict';

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

app.controller('MainCtrl', function ($scope) {
    $scope.$watch('amountone + amounttwo', function() {
        $scope.ratioone = $scope.amountone / $scope.amounttwo;
        $scope.ratiotwo = $scope.amounttwo / $scope.amountone;
    });
});

Putting this in $watch instead of making it a function means that the computation will only occur when the value of amountone or amounttwo is actually changed. In the other example, it would occur every time that scope changes need to be checked.

Although it may be considered over-engineering in this case, it doesn't increase complexity and lends itself to readability.

This method is also good practice, because it helps maintain forward compatibility. For instance, someone may refactor this into a directive in 3 months so that they can throw it into a grid of records. Each item could have it's own rationone and ratiotwo. If there are 1000 items in your grid, then you've just potentially saved thousands of unnecessary computations. This is only one example, and these things happen all the time.

Sign up to request clarification or add additional context in comments.

3 Comments

But isn't bad practice to use $watch in controller (or any kind of logic)?
@fabio I've never heard of that as bad practice. Why would it be bad practice? Do you have any article describing that?
@fabio I should not that although I think that $watch still isn't "bad practice", there are usually better practices. For instance, you could only change the value when an event occurs that changes the factors that it relies on. The question only gave enough scope for $watch to be the right answer, but there are probably better solutions here as well. One example is that it'd be more efficient to use ngChange instead of $watch if this were changed within an input. I just don't have enough information to know the way that the data is being updated.
1

Use a function to do your calculation and return the result, then actually bind that function. The return value will be used for the binding.

$scope.ratioone = function() {
  return $scope.amountone / $scope.amounttwo;
};

HTML:

Test ratio: {{ amountone }}/{{ amounttwo}} = {{ ratioone() }}

Live demo (click).

Please also note that <br> should not be used for spacing in a layout. It is just for newlines within text like:

<p>This is some text.<br>And this is some more text.</p>

For layout spacing, apply CSS rules like margin, padding and display: block.

1 Comment

I actually tried this, but it didn't work because I made the mistake of using the variable like this {{ ratioone }} instead of this {{ ratioone() }}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.