This is a common question/concern by those seeing angular for the first
time. In a sense, it seems as though we’ve gone backwards in time when we
used to do things like:
<div onclick="doSomething()">
About the time that jquery started becoming popular, a lot of the
web-development community got sold on “unobtrusive javascript” which a
large part of it meant you would clean the dom from all javascript and then
attach javascript handlers entirely from within a script. One of the
greatest benefits of this approach as it evolved is that it freed us to a
large extent form having to define our handlers globally. We could now
create our handlers in modularized non-global code and then attach them
directly to the dom, and this is the main concept with a lot of the
jquery-based frameworks such as backbone.js.
However, this style of programming did not come without it’s downsides.
While the intent was to keep javascript unobtrusive, in practice both the
javascript and the dom intruded on each other all over the place.
The dom became filled with extra markup and classes unrelated to style to
make it selectable as well as to hold state:
<div>
<span class="show-person-details" data-person-id="42">Person 2<span>
<div class="person-details hidden" data-person-id="42">This is the
details</div>
</div><div>
<span class="show-person-details" data-person-id="43">Person 1<span>
<div class="person-details hidden" data-person-id="43">This is the
details</div>
</div>
The javascript became littered with complex selector expressions, css
classes, and lots of dom manipulation code:
$('.show-person-details').click(function(ev){
var personSpan = $(ev.target);
var personId = personSpan.data("person-id");
$('.person-details[data-person-id='+personId+']).removeClass("hidden");
});
This is just a simple example, on many a real-world project this can get
much worse. In any case the dom clearly intruded into the javascript, and
the javascript intruded into the dom (in the form of unecessary selectors
and data attributes, hidden inputs, etc…).
The philosophy of angular is to elminate the real fundamental issue we had
with onclick= style handlers which is the fact that they were global. It
does this by creating a scope hierarchy (controlled by Controllers and
Directives) that allows you to map state neatly and in a modular fashion
onto the DOM tree we are all familiar with.
I can do the equivalent of the above example purely in the html (assuming
that persons object already exists in our scope):
<div ng-repeat="person in persons">
<span ng-click="person.detailsVisible= true">{{person.name}}<span>
<div ng-show="person.detailsVisible">{{person.details}}</div></div>
This is very easy to understand, even for someone who’s never used angular.
Simply by looking at the markup I can tell exactly what the behavior of
this will be. Furthermore, I’ve removed the need to do any custom
javascript logic or dom manipulation in order to show/hide the details.
While it might not be incredibly difficult in the simple jQuery example
above to tell what the code might do, I’ve often have had to jump on
existing large projects where figuring out what the page is supposed to do
is an incredibly difficult task. The DOM is litered with classes, but which
ones are for style? Which ones are to make it easier to use selectors to
bind some event? How do I know what’s clickable, and how different parts of
the page might be related? How am I supposed to know that deep down in some
obscure part of the code some event is bound that does something I did not
expect?
Sure, with discipline, great care, and tight organization you can alleviate
some of the pain, but I’ve been on projects with very talented developers
and strict code organization that still eventually become somewhat of a
mess.
One of the difficulties I think you will face is in trying to integrate
with your existing way of doing things.
While angular itself is fairly low-level, flexible, and certainly not as
perscriptive as some other frameworks (e.g. ember.js), you will still run
into quite a bit of friction if you don’t do things “the angular way”.
What people often mean when they say “the angular way” is really just
designing the application in a more declarative way. This is fundamentally
different than the imperative patterns people are used to from using
jQuery.
In the first person/details example above the code is entirely imperative.
The click calls a click handler which instructs the browser to lookup a
piece of dom and hide it. The click is tightly coupled to what must happen
as the result of the click.
In the angular (declarative example) we break things up into independent
actions. The click simply sets the state detailsVisible on the person. The
details simply is setup to show the details whenever the detailsVisible
flag is true. It is completely decoupled from the click action. It doesn’t
care whether the detailsVisible flag was set by a click handler, by
javascript code, by some bound checkbox, loaded from the server that way,
etc….
It’s hard to go into further detail without talking specifics, but rest
assured that when used correctly, angular provides all the tools necessary
to create very modular, well-encapsulated, and testable code that respects
separation of concerns more than most any other javascript framework out
there. However, it won’t likely do this with the same patterns as you are
used to using. It really will necessary to rethink things and establish new
patterns if planning on using angular.
If you would like to post some simplified code examples (preferably in
plunkr or jsfiddle) of how you do things now with your home-grown
libraries/frameworks, we could discuss what the equivalent way of doing the
same in angular.js would be and compare/contrast.
--
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.