0

Being new to AngularJS my understanding of the below syntax, from my limited experience, was that it made a two-way data binding between the view and model which means if the input in the view changes the model changes to match AND vice versa.

<form ng-controller="StartUpController">
     Starting: <input ng-change="computeNeeded()"
                       ng-model="funding.startingEstimate">
     Recommendation: {{funding.needed}}
</form>

<script>
    function StartUpController($scope) {
         $scope.funding = { startingEstimate: 0 };
         $scope.computeNeeded = function() {
              $scope.needed = $scope.startingEstimate * 10;
         };
    }
</script>

Then I read that if other elements are bound to the same variable in the model or if the database may update the model then $watch() must be used so that the view updates. But from my novice perspective this is what two-way data binding is doing already.

<form ng-controller="StartUpController">
     Starting: <input ng-model="funding.startingEstimate">
     Recommendation: {{funding.needed}}
</form>

<script>
function StartUpController($scope) {
     $scope.funding = { startingEstimate: 0 };
     computeNeeded = function() {
            $scope.funding.needed = $scope.funding.startingEstimate * 10;
     };
     $scope.$watch('funding.startingEstimate', computeNeeded);
} 

Could someone clarify for me... Many Thanks in advance.

1 Answer 1

2

If this is the exact code you have, then the problem is likely that you just didn't refer to your scope properties correctly, not that the two way databinding doesn't work.

Your script tag should be:

<script>
    function StartUpController($scope) {
         $scope.funding = { 
             startingEstimate: 0,
             needed: 0
         };
         $scope.computeNeeded = function() {
              $scope.funding.needed = $scope.funding.startingEstimate * 10;
         };
    }
</script>

EDIT: Just to explain further, the two code samples you provided (if the scope properties are referenced correctly) are equivalent if the user is the only one who will change the value of funding.startingEstimate. If anything else, like a DB update, etc, can update that value, then using the $watch() on that property is the only way to compute another value every time it changes, whether by the user or some other means.

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

6 Comments

The code is taken from Brad Green's O'Reilly book on AngularJS. I figured that in the second script tag computeNeeded was only referenced locally and therefore didn't need to be added to the $scope for the view. This is not my code and I just wanted to use it as a example to help someone clarify the difference between two-way data binding and having a $watch() set up. But you say this is an equivalent? Are there no subtleties I should be aware of?
So i think I understand a little better after re reading your answer twice more. The 'subtleties' are in the call to the function. The function's recalculation is bound to an event on our element, not to the model. $watch() allows us to attach functionality to be called when the model is changed by anything other than our element. Correct?
Yes, your second comment is correct. The "two-way databinding" feature of AngularJS is pretty much all to do with ng-model. If you look at its source code you will see that it sets up a $watch on line 1830. That binds from the model to the input value. The other way is handled by event handlers set up to call $setViewValue().
Another thing to be aware of is that lots of things in Angular use $watch() implicitly under the covers. Even using {{curly_braces}} in your markup will set up a watch on the "curly_braces" expression. Other ones are isolate scope properties for directives, and many more. $watch() is the main way that Angular can react to almost any change.
So an explicit call to $watch() is our way of binding things in the controller 'back-end' that are not already bound by virtue of our directives and expressions. Clarity, cheers.
|

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.