2

My directive with controller :

app.directive("photoGallery", function() {
    return {
        restrict: 'E',
        templateUrl: 'part/photoGallery.html',
        controller: ["$http", function($http) {
            me = this;
            this.autoSlide = true;
            this.currentIndex = 2;
            this.autoSlide_timer;
            this.photos = [{}];

            this.Show = function(index) {
                me.currentIndex = index;
            };

            this.Next = function() {
                me.currentIndex++;
                console.log(me.currentIndex);
                if (me.currentIndex >= me.photos.length) {
                    me.currentIndex = 0;
                }
                me.Show(me.currentIndex);
            };

            this.Prev = function() {
                me.currentIndex--;
                if (me.currentIndex < 0) {
                    me.currentIndex = me.photos.length-1;
                }
                me.Show(me.currentIndex);
            };

            this.Init = function() {
                $http.get("img/slider/_data.json")
                .success(function(data) {
                    me.photos = data;
                    for(var i in me.photos) {
                        me.photos[i].index = i;
                    }
                    console.info(me.photos);
                })
                .error(function(e){
                    console.error(e);
                });
                this.autoSlide_timer = setInterval(this.Next, 1500);
            }();
        }],
        controllerAs: 'gallery'
    };
});

photoGallery.html :

<div class="GalleryContainer">{{gallery.currentIndex}}
    <div class="PhotoWrapper">
        <div ng-repeat="photo in gallery.photos" class="photo" ng-class="{active:gallery.currentIndex == photo.index}">
            <img ng-src="img/slider/{{photo.path}}">
        </div>
    </div>
</div>

as you can see, in the Next() function, I log currentIndex Next() is called every 1500ms thanks to setInterval(this.Next, 1500) in the Init() function. I can see in the console : 2, 3, 4, ... 10, 0, 1, 2 ...

But in the browser, {{gallery.currentIndex}} is never updated, it display the default value (2) (photoGallery.html line 1)

Apolo
  • 3,844
  • 1
  • 21
  • 51
  • 1
    use [`$interval`](https://docs.angularjs.org/api/ng/service/$interval) service instead of `setInterval` – Rahil Wazir Jul 22 '15 at 20:43
  • Like @RahilWazir mentioned, use `$interval` or make a manual call to `$scope.$apply()` in your interval function (`this.Next`). `setInterval` exists outside the angular scope so you won't get any 'auto update' functionality. – csbarnes Jul 22 '15 at 20:45
  • Thanks, but in my controller, `this`refers to the window element... (I did `console.log(this);` at the end of Init()) – Apolo Jul 22 '15 at 20:49

1 Answers1

1

You have to use angular $interval() instead of JavaScript setInterval() function. Why ?

Because Angular needs to know when variables are updated. $interval make a call to $scope.$apply() at the end of its execution, executing a new $digest loop that notify the update to angular.

You can also wait the request to be successfully proceed to set you interval, to avoid errors.

this.Init = function() {
    $http.get("img/slider/_data.json")
    .success(function(data) {
        me.photos = data;
        for(var i in me.photos) {
            me.photos[i].index = i;
        }
        console.info(me.photos);

        me.autoSlide_timer = $interval(me.Next, 1500);
    })
    .error(function(e){
        console.error(e);
    });
}();
Freezystem
  • 4,494
  • 1
  • 32
  • 35
  • Its not `$setInterval`, its `$interval` – Rahil Wazir Jul 23 '15 at 05:09
  • I guess `$interval` was one of my problems, thanks. But it seems like I have a scope problem: in controller's functions, `this` refers to the window element (top DOM element) – Apolo Jul 23 '15 at 13:02
  • Have you tried to refer to window using angular `$window` instead of `this` ? – Freezystem Jul 23 '15 at 13:08
  • I want `this` to refer to the Model. – Apolo Jul 23 '15 at 13:27
  • so when I declare `this.Next = function () /*...*/` in the controller, Next become a method of my model – Apolo Jul 23 '15 at 13:28
  • Why don't you use `$scope` instead of `this`. The behaviour is a bit different from one to another. You can find more details looking to [http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers#answer-14168699](this answer) – Freezystem Jul 23 '15 at 14:22
  • because I never heard of $scope, just seen a few scripts with it. I just needed to use the `me` variable instead of this. – Apolo Jul 24 '15 at 17:45