10

i like to make a custom component using directive. i checked lot of tutorials and its get confusing me can anyone explain how a directive works. the component i am planing to make is

<shout-list></shout-list>

the template for shout list will be like this

<div class="shout" ng-repeat="shout in shouts">
    <p>{{shout.message}}</p>
    <img src="media/images/delete.png" width="32" height="32" ng-click="deleteShout({{$index}},'{{shout._id}}')"/>
</div> 
Jaison Justus
  • 2,753
  • 8
  • 47
  • 65
  • Short videos from [egghead.io](http://egghead.io/) helps me to understand directives. And videos from blogpost [About those directives](http://blog.angularjs.org/2012/11/about-those-directives.html) from official AngularJS blog. – Maxim Ponomarev Jan 31 '13 at 08:42
  • i watched the video but i am confused in when to use compiler and linker – Jaison Justus Jan 31 '13 at 09:42
  • 1
    In common words: compiler should used for modify the template, linker for binding data to the compiled template – Maxim Ponomarev Jan 31 '13 at 10:19
  • @MaximPonomarev in which case do you use compiler and linker? can you specify on situation when we are gonna use it.. – Jaison Justus Jan 31 '13 at 10:42
  • The compile function deals with transforming the template DOM. The link function is responsible for registering DOM listeners as well as updating the DOM. For example, directive `ng-repeat` transform the DOM and use compiler, `ng-switch` just manipulate the DOM and use linker. Look at angular source for understand how works built-in directives. – Maxim Ponomarev Jan 31 '13 at 11:04
  • 1
    I wrote a blog article to get people started writing directives: http://seanhess.github.io/2013/10/14/angularjs-directive-design.html – Sean Clark Hess Oct 15 '13 at 00:21

1 Answers1

16

Here's your directive, with some inline comments:

angular.module( 'directives', [] ).directive( 'shoutList', function () {
  return {
    restrict: 'E', // allow as an element; the default is only an attribute
    scope: {       // create an isolate scope
      shouts: '='  // map the var in the shouts attribute to this scope
    },
    templateUrl: 'templates/shoutList.html', // load the template file
    controller: function ( $scope ) {
      // we declare a your function for use in the view
      $scope.deleteShout = function ( idx, id ) {
        // do whatever
      };
    }
  };
});

And the template file:

<div class="shout" ng-repeat="shout in shouts">
  <p>{{shout.message}}</p>
  <img src="media/images/delete.png" width="32" height="32" 
    ng-click="deleteShout({{$index}},'{{shout._id}}')" />
</div> 

And now you can use it in your code, like so:

Controller:

.controller( 'MainCtrl', function ( $scope ) {
  $scope.myShouts = // ...
});

View:

<shout-list shouts="myShouts"></shout-list>

Hope this helps!

Josh David Miller
  • 120,525
  • 16
  • 127
  • 95
  • thank you very much. in which case we use compiler and linker methods. if possible can you explain by concatenating to the answer above. – Jaison Justus Jan 31 '13 at 09:41
  • 1
    @Jaison, see [difference between compile and link function](http://stackoverflow.com/a/14300374/215945) – Mark Rajcok Jan 31 '13 at 18:55
  • @Josh, do you have an opinion about where the deleteShout function should be defined: as you show in a controller vs defining it in the link function: `link: function(scope) { scope.deleteShout = function(...) {...} }`? – Mark Rajcok Jan 31 '13 at 19:16
  • 1
    @MarkRajcok Only a very weak opinion. As I understand it, there are only a few subtle differences between the controller and link functions (e.g. ctrls run first), but that none of those impact this example. To me, it makes more sense for scope-manipulation functions to occur inside a controller just for consistency with the rest of the framework, but it doesn't really matter. But really, in this case I wouldn't even do `deleteShout` in the directive; the directive should focus on the DOM stuff and should call an '&' attr to do the actual deletion, what with separation of concerns and all... – Josh David Miller Jan 31 '13 at 19:40
  • Thanks. After I posted the comment I was also wondering if the deletion functionality might be better elsewhere, so thanks for reading my mind and covering that too. – Mark Rajcok Jan 31 '13 at 20:31
  • @JoshDavidMiller how can i connect the deleteShout method defined in the controller with the directive – Jaison Justus Feb 01 '13 at 08:47
  • @JaisonJustus I'm not sure what you mean - it already is. From your template, `ngClick` triggers that scope method when your `img` is clicked. – Josh David Miller Feb 01 '13 at 17:39
  • 5
    @Jaison, in case it isn't obvious: when you define a controller inside a directive like Josh shows, then, every place where you use the directive in the HTML, a controller is created and it is automatically associated with the directive's scope. It is almost as if "ng-controller" were added wherever you use the directive. – Mark Rajcok Feb 02 '13 at 02:59