I see where you are coming from. You have an established set of patterns 
which work well for you. However, in many ways angular makes a lot of these 
patterns potentially unecessary, and by adopting new patterns more aligned 
with the angular way of doing things, you can greatly reduce the complexity 
and amount of code, while still retaining (and in many cases improving) 
modularity, re-usability, testability, and separation of concerns. 

I think one of the confusions here is the way that so-called angular 
“templates” work. Angular templates are not a string-based templating 
system like many other stystem. Angular templates always start as a tree of 
real browser DOM nodes before any directives are actually applied. 

I might be wrong, but I get a feeling you might not be fully understanding 
what directives really are. Angular directives are not language constructs, 
they are simply snippets of javascript that run as angular encounters them 
when it walks down the DOM tree. These snippets run in the context of the 
current scope and the element that they were encountered in. This 
javascript is then responsible for doing whatever it needs to do, often 
decorating the dom or removing/adding new elements or cloning dom and 
repeating it. 

If you are familiar with jquery, let me show you what the equivalent of a 
directive would be in jquery. Say we have this html:

    <p weight="900" > This is my text</p>

Weight is not a real property in html, but we’d like it to mean what the 
CSS font-weight should be for this paragraph (I know this would be better 
done with a class+css but this is just a simple example).

The jQuery would be like this:

$('[weight]').each(function(index, element) {
    console.log(index, element);
    $(element).css('font-weight', $(element).attr('weight'));
  });

The equivalent angular directive would be:

app.directive('weight', function(){
    return{
       restrict: 'A',
       link: function(scope, element, attrs){
        element.css('font-weight', attrs.weight);
       }
     }
});

As you can see, a directive is just a different syntax for binding 
javascript behavior to a dom element. They are very much like writing 
jquery selectors that then applying some javascript code to the results. 
The directive only support a limited number of ways to match (rather than 
the full selector engine). So for example these following are different 
directive types along with equivalent jQuery:

Attribute directives: 

$('[some-attribute]').each(......do stuff....)

app.directive('someAttribute', function(scope, element, attrs){
    return {
         restrict: 'A', 
         link: function(){
             ...do stuff..      
         }
    };
 });

Element directives: 

$('some-element').each(......do stuff....)

app.directive('someElement', function( scope, element, attrs){
    return {
         restrict: 'E',   
         link: function(){
             ...do stuff..      
         }
    };
 });

Class directives: 

$('.some-class').each(......do stuff....)

app.directive('someClass', function(){
    return {
         restrict: 'C',   
         link: function(scope, element, attrs){
             ...do stuff..      
         }
    };
 });

To go back to your originally question, I hope it is now clear that the 
only difference between element directives or attribute directives, or 
class directives, is how angular matches the dom element in question. Once 
it has matched the element, the link function will be called with the 
matching element. In fact, it is common practice when using element 
directives to have them match both on elements and on attributes:

Element OR Attrtibute directives: 

$(['person-selector', '[person-selector]']).each(......do stuff......)

app.directive('someClass', function(){
    return {
         restrict: 'EA',   
         link: function(scope, element, attrs){
             ...do stuff..      
         }
    };
 });

This way people have the choice of how to actually use the directive if 
they aren’t comfortable with having non-html nodes on their page.

Hopefully this helps clarify that directives really are just a way to 
associate a bit of javascript with a dom node.

Of course angular does provide some sugar on top of directives to make some 
common actions easier. For example directives can have templates. Say I 
have a <hello/> directive that simply replaces itself with a paragraph <p>HELLO 
WORLD!</p>:

app.directive('hello', function(){
  return {
    restrict: 'E',
    template: '<p>HELLO WORLD!</p>',
    replace: true
  };
});

Underneath the hood though, this is really still just matching any 
<hello>elements, and executing javascript that replaces it with new dom. You 
could 
even write this with the lower-level construct:

app.directive('hello', function(){
  return {
    restrict: 'E',
    link: function(scope, element, attrs){
      element.replaceWith('<p>HELLO WORLD</p>');
    }
  };
});

Hopefuly this sheds some light and ‘demistifies’ directives. I apologize if 
I’m telling you things you may already know but it may be helpful to others 
since there seems to be some confusion out there about what directives 
really are. 

I’m sure I still haven’t done enough to convince you of the benefits of 
doing things “the angular way”. And to be honest, it is difficult to do 
without taking an existing real-world example, implementing the “angular 
way” and then exploring any benefits/drawbacks in the different approaches. 

If you’d like to provide some more complete and preferably working examples 
in a plunkr, I would be happy to show what I would consider the “angular 
way” of implementing the same functionality and then discuss any 
thoughts/concerns you might have.

-- 
You received this message because you are subscribed to the Google Groups 
"AngularJS" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to angular+unsubscr...@googlegroups.com.
To post to this group, send email to angular@googlegroups.com.
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to