BT101
BT101

Reputation: 3836

Two way data binding doesn't work from directive link function angularjs

I'm trying to use variable declared in directive' link: function in directive view html.

Variable which I'm trying to use is int from object which is (this object) declared as $scope variable named slider.

I'm trying to display it:

<div>
    {{ slider.step }}
</div>

And printed value is aa : 1 and it's not changing althougt it should be. It's constantly 1 and it don't want to rebind :( although I'm changing this value in code later on. Take a look at full directive code. I'm changing its value in few places:

..in directive link function..

link: function($scope, el) {
  $scope.slider = {
    step: 1,
    changeSlide: function (step) {
      if(step === 1) {
        this.step = 1;
        console.log('changed step to 1: ' + $scope.slider.step);
      }
      if(step === 2) {
        this.step = 2;
        console.log('changed step to 2: ' + $scope.slider.step);
      }
    }
  }
  $timeout(function () {
    var i = 1;
    $scope.slider.changeSlide(i);
    setInterval(function () {
        i++; if(i === 3) i = 1;
        $scope.slider.changeSlide(i);
    }, 5000);
  });
}

I'm chaning step in if(step === 2).

Basically that's correctly working vertical slider. The only missing thing is that I can't access current step from view and I can't display correct active dot of "which slide is currently selected". That's why I need to get this step int in view but I can not.

Here is plnkr demo.

Upvotes: 0

Views: 587

Answers (1)

Saeed
Saeed

Reputation: 5488

You must use $timeout(function(){ $scope.$apply(); }); after data changed

Working example

angular.module('plunker', []);

function MainCtrl($scope) {
  $scope.hello = 'World';
}

angular.module('plunker').directive('elements', function($timeout) {
  return {
    restrict: 'E',
    scope: {
      name: '='
    },
    template: `<div>
    {{ slider }}
</div>`,
    link: function($scope, el) {

      $scope.slider = {
        step: 1,
        changeSlide: function(step) {
          console.log(11, step)
          if (step === 1) {
            this.step = 1;
            console.log('changed step to 1: ' + $scope.slider.step);
          }
          if (step === 2) {
            this.step = 2;
            console.log('changed step to 2: ' + $scope.slider.step);
          }
          $timeout(function(){ $scope.$apply(); });
        }
      }
      var i = 1;

      $timeout(function() {
        $scope.slider.changeSlide(i);
        setInterval(function() {
          i++;
          if (i === 3) i = 1;
          $scope.slider.changeSlide(i);
        }, 5000);
      });
    }
  };
});
<!doctype html>
<html ng-app="plunker">

<head>
  <meta charset="utf-8">
  <title>AngularJS Plunker</title>
  <link rel="stylesheet" href="style.css">
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <script>
    document.write("<base href=\"" + document.location + "\" />");
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <elements></elements>
</body>

</html>

Upvotes: 1

Related Questions