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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/angular.
For more options, visit https://groups.google.com/groups/opt_out.