Reputation: 835
I'm trying to understand how Angular data binding works. I have created this sample that displays {{values.count}}
inside a span
element:
<body ng-app="testApp" ng-controller="testCtrl as values">
<span>Count = {{values.count}}</span>
<button id="incr">++</button>
</body>
<script>
testApp = angular.module("testApp", []);
testApp.controller("testCtrl", function () {
var values = this;
values.count = 5;
$("#incr").on('click', function () {
values.count += 1;
});
});
</script>
If I click on the button, values.count
is incremented, but the span
is not updated. I can get it to work if I place a ng-click="values.Increment()"
on the button and create a values.Increment
method in the controller, but what is the difference that makes one work and the other not?
Upvotes: 1
Views: 1847
Reputation: 123739
You are doing it the wrong way. When using angular, you don't need to bind event handlers/access DOM elements for this purpose. Use built-in ng-click
directive.
<button ng-click="values.incr()">++</button>
and
values.incr = function(){
values.count++;
}
You could even do it inline, <button ng-click="values.count = values.count+1">++</button>
The reason why your code did not update DOM is because of the way angular works. Even though you are incrementing the value inside the manually bound event handler angular is unaware of the update and it does not update DOM binding with the new value. Though a bad practice in your specific case you can achieve that by doing $scope.$apply()
(but ofcourse you need to inject $scope
in your controller) as well inside the event handler to manually invoke the digest cycle. General thumb rule when working with angular is the controller do not access DOM directly, Instead it just sets up data for the view and with the help of bindings and other built-in or custom directives you get the intended behavior in your application.
Read about scope life cycle and digest cycle
Upvotes: 3