adam
adam

Reputation: 555

Angular How to better use my service

I have a service who is generating the shape of a gallery of pictures.

when i arrive for the first time in the view everything is alright but when i go to another one and come back to the view with the gallery, the service seems to be not called because nothing happens...

Here's the service:

'use strict';

angular.module('myApp')
  .service('displayGal', function(){

        var displayGallery = function(){
          var images = document.getElementById('flickr_gallery').children;

        var padding = 10,
            columns = 3,
            leftPosition,
            topPosition;

        for(var i = 1; i < images.length; i++){
            if(i % columns === 0){
                topPosition = (images[i-columns].offsetTop + images[i-columns].offsetHeight) + padding;
                images[i].style.top = topPosition + 'px';
            }else{
                if(images[i-columns]){
                    topPosition = (images[i-columns].offsetTop + images[i-columns].offsetHeight) + padding;
                    images[i].style.top = topPosition + 'px';
                }
                leftPosition = (images[i-1].offsetLeft + images[i-1].offsetWidth) + padding;
                images[i].style.left = leftPosition + 'px';
            }
        }
      }
        window.addEventListener('load', displayGallery, true);
        window.addEventListener('resize', displayGallery, true);
  });

and i'm injecting it like that in my controller:

angular.module('myApp')
  .controller('MainCtrl', function ($scope, displayGal) {
...
...etc

What am i doing wrong?

Upvotes: 0

Views: 38

Answers (1)

GregL
GregL

Reputation: 38151

For a start, this sort of DOM manipulation does not belong in a service. It belongs in a directive.

Secondly, is there a reason you are doing manual DOM manipulation instead of using Angular directives and bindings?

Thirdly (and the real answer to your immediate problem), services are singletons in Angular. The first time they are injected, they get instantiated, and the result is stored for all subsequent injections. Since your service function doesn't return anything, the value of undefined will be used for injecting into MainCtrl. If you must do this as a service, change to using .factory() instead of .service() and return a new function every time that will do the work. Then call that function inside your MainCtrl.

e.g.

angular.module('sainsburysTest')
       .factory('displayGal', function(){
            var displayGallery = function () {
            ...
            };
            return displayGallery;
       });

 angular.module('sainsburysTest')
        .controller('MainCtrl', function ($scope, displayGal) { 
             displayGal();
             ...
        });

Though I have to stress again this is not a good idea. Not least because you cannot unregister your event handlers on window when you navigate away from that page. This is a quick path to memory leaks.

Whereas, if you do it in a directive, you can listen to the $scope.$on('$destroy', function () { ... }); event and then remove the event listeners on window correctly.

Upvotes: 1

Related Questions