Apples
Apples

Reputation: 337

Avoiding too many Angularjs Directives

I have the following directive:

.directive('myDirective', function() {
   restrict: 'A',
   templateUrl: 'app/templates/someTemplate/html',      
});

in my template (someTemplate.html) I have the following:

<div>
  <div>Some div</div>
  <input type="button" value="button" />
</div>

I want to add behavior to the button and div. I can go the route of adding directives like so:

<div>
  <div div-click>Some div</div>
  <input type="button" value="button" button-click />
</div>

and adding more directives and binding click events via element.bind(... but is there a best practice? Should I be adding behavior in the 'myDirective' containing those elements? via jQuery or jQlite . The clickable elements inside the template are not meant to be resuable..so should I just use jQuery to find those elements and bind event listeners to them? I can see how their can be a directives explosion by constantly using the directive route, what is the best practice?

Upvotes: 2

Views: 1096

Answers (1)

Florian
Florian

Reputation: 3366

The question for me would be on what exactly the directives should be for.

It sounds to me, as if you are trying to wrap functionality that you know from other frameworks like jQuery into directives. this leads to stuff like:

var app = angular.module("module.directives", []);
app.directive('myDirective', function() {
   restrict: 'A',
   templateUrl: 'app/templates/someTemplate/html',
   link: function(scope, el) {
     el.on("click", function() { console.log(42); });
   }
});

While certainly possible, this is (at least for me) considered "bad" style. The difference with Angular is, that it does not use the DOM as the "Model" part of the framework, like jQuery or Prototype do. Coming from these libraries this is something to wrap your head around, but actually, for starters, it boils down to this:

Work with the scope and let the changes to the scope be reflected in the DOM.

The reflection part is actually the short and easy one: Angular does this out of the box (i.e. "most of the time").

Reconsidering your example with the click - Angular provides excellent event handlers in the form of directives. ng-click is a very good example for this:

<div>
  <div ng-click="method()">Some div</div>
  <input type="button" value="button" ng-click="method2()" />
</div>

This directive takes an expression - it looks a bit like the old days, where you would bind javascript directly to elements, like this:

<a href="#" onclick="method()">here</a>

It's way different though - Angular will look for the names method and method2 on the current scope you are in. Which scope you are currently in depends on the circumstances (I heavily suggest the docs at this point)

For all of our intents and purposes, lets say, you configure a controller inside your directive from earlier:

var app = angular.module("module.directives", []);
app.directive('myDirective', function() {
   restrict: 'A',
   templateUrl: 'app/templates/someTemplate/html',
   controller: ['$scope', function(scope) {
     scope.active = false;
     scope.method = function() { console.log(42); };
     scope.method2 = function() { scope.active = !scope.active };
   }]
});

You can define this in many places, even as late as during the link phase of a directive. You can also create an extra controller in a separate module. But let's just stick with this for a moment:

In the template - when you click on your div the scope's method will be called. Nothing fancy, just console output. method2 is a little bit more interesting - it changes the active variable on the scope. And you can use this to your advantage:

<div>
  <div ng-click="method()">Some div</div>
  <input type="button" value="button" ng-click="method2()" />
  <span ng-show="active">Active</span>
</div>

When you click on your button, the span will be turned on and of - the ng-show directive handles this for you.

This has gotten a bit longer than expected - I hope though, that this sheds some light on the "best practises" (which are quite dependent on what you actually want to accomplish).

Upvotes: 6

Related Questions