Raja
Raja

Reputation: 6824

two way databinding in angular not working as I expected

I'm trying to test a simple databinding concept after going thru angular documentation.

This is the sample html file

<body ng-app>
  <h1>Hello, world!</h1>
  <div ng-controller="Ctrl">
    <input type="text" ng-model="count" />
    COUNT: <span ng-bind="count"></span>
  </div>
</body>

And this is the Ctrl function

var i = 0;
function Ctrl($scope) {
  $scope.count = i;
  inc();
}

function inc() {
  i++;
  setTimeout(inc, 1000);
}

I was expecting that the COUNT in html will keep updating as the var i is incremented every sec in the javascript.

But it doesn't work that way.

I'm trying to find what is wrong with my code and what is a good example to demo the concept of two way databinding (meaning when javascript object is changed it should be reflected in html)

Upvotes: 0

Views: 500

Answers (2)

Yoshi
Yoshi

Reputation: 54659

Two problems:

  1. $scope.count = i; will not be a reference to the global i and thus, regardless of the next problem, would not update (this is not an angular problem).

  2. Your interval function would update the counter without angular noticing it. To overcome this problem use $apply or special angular helpers, e.g. $timeout

A working example would be:

(function (app, ng) {
  'use strict';

  app.controller('Ctrl', ['$scope', '$timeout', function ($scope, $timeout) {
    $scope.count = 0;

    (function _update() {
      $scope.$apply(function () {
        $scope.count += 1;
      });

      $timeout(_update, 1000);
    }());
  }]);
}(angular.module('app', []), angular));

demo: http://jsbin.com/unasaf/1/


or a less complicated version would be:

function Ctrl($scope, $timeout) {
  $scope.count = 0;

  $scope.increment = function increment() {
    $scope.count += 1;
  };

  (function _update() {
    $scope.increment();    
    $timeout(_update, 1000);
  }());
}

Upvotes: 2

John Woodruff
John Woodruff

Reputation: 1666

Use the following code:

JS:

function Ctrl($scope, $timeout) {
$scope.count = 0;

$scope.increment = function(){
    $scope.count++;
    $timeout(function(){
        $scope.increment();
    }, 1000);
}

$scope.increment();
}

HTML:

  <body>
    <h1>Hello, world!</h1>
    <div ng-controller="Ctrl">
    <input type="text" ng-model="count" />
    COUNT: <span ng-bind="count"></span>
    </div>
  </body>

Upvotes: 0

Related Questions