0

I'm creating a product gallery directive in Angular, which will allow the user to scroll through images with left/right arrows.

What is the most appropriate angular approach to feed my directive with the array of image URLs?

You can assume that the parent controller has already made an API call to receive this the array of URLs

E.g.

<div data-ng-controller="MyController as myController">
    <my-image-gallery></my-image-gallery>
</div>

Should I just have an attribute of that takes in the JSON array? Perhaps something like:

<my-image-gallery images="myController.ImageList"></my-image-gallery>

Although, I'm not even sure if the above is possible. It would mean the JSON would have to be converted into a string?

There must be a better way

Edit

As per comments, I've tried the above method, but I can't access the "images" field from within my controller.

Here is what I have defined in my directive:

    scope: {
        imageSource: '='
    },

Then in my controller, I assume I should just be able to reference the variable imageSource, shouldn't I?

6
  • if directive is just being used as template it will inherit parent scope if internal scope isn't isolated. better is dependent on use case. Your understanding about needing to convert to string is incorrect also Commented Oct 3, 2015 at 21:29
  • Thanks. It's not solely used as a template; there will be controller code (left/right arrow buttons) to "scroll" the image. I wanted to isolate the scope of the directive so it doesn't depend on the parent having a certain field. So in this case, would my approach of sending the ImageList array into the directive via an attribute suffice? Or is there a cleaner way? @charlietfl Commented Oct 3, 2015 at 21:37
  • 1
    sure, just set the scope in directive to match Commented Oct 3, 2015 at 21:39
  • Hmmmm... So I'm using the approach described above. How do I access the "images" object from within my controller code then? I've tried self.images and $scope.images, and none of them work. @charlietfl. I'll update my question to reflect this Commented Oct 3, 2015 at 21:52
  • It does not need to be converted in to a string. The attribute can take the object (array) directly. Just try it before asking. You can't break anything. If it doesn't work then come back. Commented Oct 3, 2015 at 21:52

1 Answer 1

1

I think you're using a kinda weird tutorial or something to learn angular. You can use the MyController as MyController syntax, but the goal of that is to avoid using $scope. I personally don't agree with it and don't understand why people would want to do that.

When you attach a value to $scope it becomes available in your view directly (without needing $scope). For example, $scope.images would be passed in to your directive as just images.

To have the directive process that value as a variable instead of a string it must be defined using an = (as opposed to an @) you can read more about this in the angular directive docs

Here is an example of how this would work:

Javascript

angular.module('app',[])

.controller('myCtrl',['$scope',function($scope){

  $scope.imageList=['img1','img2','img3','img...'];

}])

.directive('myImageGallery',function(){
  return {
    restrict: 'E',
    scope:{
      images:'='
    },
    controller: ['$scope',function($scope){
      console.log($scope.images);
    }],
    replace: true,
    template: '<ul><li ng-repeat="img in images">{{img}}</li></ul>'
  }
})

HTML

  <body ng-app="app">
    <div ng-controller="myCtrl">
      <my-image-gallery images="imageList"></my-image-gallery>
    </div>
  </body>

and here is a plunker of it in action.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks @Lenny! So is there any way to do this without $scope?
Yes, you can do myCtrl as myCtrl and then myCtrl.imageList and in the controller instead of $scope.imageList you do this.imageList, but again... I really don't know why anyone would want to avoid $scope it is a core part of angular and it works great. When you avoid it you have to do a bunch of hacks / workarounds to make basic things like watchers work correctly.
Thanks @Lenny. One more question: Is there a way to perform some action when imageList is loaded? For example, I have a line ng-src="{{ currentImage }} in my code. So when imageList is successfully loaded, I want to set currentImage = imageList[0]. Is there a callback function to achieve this?
You could just do it in the first line of the controller (inside the directive). OR if you think the data could be changed later you could use a watcher. a $watch function can be attached to any $scope value and it will trigger whenever the value of that variable is changed. Documentation here: docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.