zuresh zuresh - 3 months ago 17
AngularJS Question

AngularJS - two way binding not working using service

I am learning Angular using W3Schools.

I just modified an example about "Services"... The following is the code:



<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">

<p><input type="text" ng-model="num"></p>
<h2>{{num}}</h2>
<h1>{{hex}}</h1>

</div>

<p>A custom service whith a method that converts a given number into a hexadecimal number.</p>

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

app.service('hexafy', function() {
this.myFunc = function (x) {
return x.toString(16);
}
});
app.controller('myCtrl', function($scope, hexafy) {
$scope.num = 200;
$scope.hex = hexafy.myFunc($scope.num);
});
</script>

</body>
</html>





When I update the textbox, the "HEX" part is not updating. Why?

Answer

Your hexafy.myFunc is called only once when the controller is initialized, hence only the initial value is converted to hex. If you want a function to be called on the value change of a scope variable in runtime, you need filters. AngularJS has a lot of inbuilt filters that are ready to use. You can also define a custom filter, just like you define services or controllers.

<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">

<p><input type="text" ng-model="num"></p>
<h2>{{num}}</h2>
<h1>{{num | hexafy}}</h1>

</div>

<p>A custom filter that converts a given number into a hexadecimal number.</p>

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

app.filter('hexafy', function() {
    return function (x) {
        return Number(x).toString(16);  // Also convert the string to number before calling toString.
    }
});
app.controller('myCtrl', function($scope) {
  $scope.num = 200;
  //$scope.hex = hexafy.myFunc($scope.num);
});
</script>

</body>
</html>

Further reading: AngularJS Filters

NOTE: A filter is a good idea if you're gonna be using the hexafy functionality at multiple places in/across views. Otherwise, it is just an overkill and the $scope.$watch method will work fine for you, as described in other answers

Comments