Some AngularJS pitfalls
branchandbound.net
branchandbound.net
The flickering UI
A quick fix would be to extract the problematic markup, place in a separate template file and leverage ngInclude[1].
If you find yourself having many instances where this is a problem, chances are you aren't doing a good enough job of breaking up your application into controllers, page components, directives, etc.
jQuery and Angular
In my opinion the example is little weak in terms of demonstrating a pitfall of AngularJS.
Based on AngularJS best practices you'll find yourself only doing any sort of DOM manipulation in the context of a directive (much like your example). Bringing jQuery into your Angular app for the sake of using .hide here probably won't make much sense. Chances are pretty good you'll leveraging directives such as ngShow[2], ngHide[3], ngIf[4] (version 1.1.5). No need to bring jQuery in for that.
If there is indeed a valid reason to bring jQuery into the project, I'd say the responsibility lies more so on the developer ensuring the dependency is met.
Minification
With the addition of ngmin[5], this isn't necessarily a pitfall just something to consider in your workflow. There is a ngmin grunt task[6] that works as advertised! I've been using it for quite some time now and never an issue.
My thought overall though is if you've conceded minification is a step in your project workflow, you'll be using tooling to make that easier. Bring ngmin into the mix and all is well.
Directives are never 'done'
I would suggest looking into using $watch[7] within the scope of that directive or making use of compile post linking over the linking used in the example. Check out the compile section [8] of the directive guide for more information there.
[1] http://docs.angularjs.org/api/ng.directive:ngInclude
[2] http://docs.angularjs.org/api/ng.directive:ngShow
[3] http://docs.angularjs.org/api/ng.directive:ngHide
[4] http://code.angularjs.org/1.1.5/docs/api/ng.directive:ngIf
[5] https://github.com/btford/ngmin
[6] https://github.com/btford/grunt-ngmin
[7] http://docs.angularjs.org/api/ng.$rootScope.Scope#$watch
My observation here is the same as what I've had for many "look how easy it is!" frameworks: A lot of frameworks sport "look how easy it is!" syntax, but using the easy/short syntax actually isn't adequate in some (sometimes most) circumstances, and often it isn't even "recommended." So you start using the longer, more explicit syntax, and all those short/sweet syntax features are out the window.
For example, the easy-to-read {{obj.prop}} data-binding syntax is basically dis-recommended here with three workarounds given (use ng-cloak, declare databindings on element attributes, externalize & `include` the offending markup). Once you have 3 different workarounds for what's basically the most fundamental framework feature, I can't help but wonder "why offer this short/sweet/brittle syntax in the first place? Most 'power users' can't really use it." The dep injection one in particular- basically any shop worth its salt is going to use a minifier on big JS applications- none of them (us) can use the short dep injection syntax. Why even teach it/include it at all?
I guess it gets people up & running faster, but eventually you have to deal with these pitfalls.
Why even teach it/include it at all?
I fear that other developers will read a comment like this three months down the road and take it hook, line, and sinker. It is in line with the narrative that AngularJS and similar tools hide their complexity/inflexibility, and that the up-front examples are marketing fluff. I know I am guilty of this when I look to comments like this one for the "on the ground" perspective.Real-world AngularJS applications use multiple templates and {{ o.p }}. {{ o.p }} is the recommended way to render scope 99% of the time.
ngmin[1] solves the DI minification/annotation problem transparently and is trivial to integrate into any existing build process.
take it hook, line, and sinker.
:( I'm not a framework developer at all, just a user; this is just my observation. Maybe it's incorrect or poorly informed, just how it appears to one person. Anyway I'm not trying to sell anyone anything, neither am I a fisher of men, so feel free to spit out my tackle. :)If it doesn't work for a real working app, the feature is either broken or shouldn't be a feature at all.
I wouldn't call ngCloak[1] a work around, it's part of the framework and specifically meant to handle this sort of thing.
Use of the ngInclude[2] is more aligned with my personal preference on how I organize and setup my projects.
The reality is though, if you are using Angular to drive your entire page (aka, everything is part of a single Angular app), the use of ngView[3] goes hand and hand to work with your routing. This brings in the view template for the route in the same way an ngInclude would for other parts of the page.
I'm drawing off my own experience in Angular development and looking at the basic examples given. If there are more complex examples that illustrate UI flicker as a real problem I'd certainly like to see them.
[1] http://docs.angularjs.org/api/ng.directive:ngCloak [2] http://docs.angularjs.org/api/ng.directive:ngInclude [3] http://docs.angularjs.org/api/ng.directive:ngView
For the "Directives are never 'done'" issue you should be able to attach any jQuery plugins to the DOM in question inside the directive compile function.
I'll have to check on your compile suggestion. I tried lots of things, including using the postLink etc. Do you have an example?
Wonder why that is, are there cases that would otherwise break?
* Don't modify the DOM with anything other than Angular, not with jQuery, not with anything. You will create a maintenance hell for yourself if you try to do things Angular isn't good at, but if you work well within it's strong areas you will achieve bliss.
* Make everything a directive if possible, Angular performs much better when you are dealing with much smaller scopes contained in directives.
* Angular watchers (including ng-repeat) can be very slow when handling large complex data sets. Create a $watch on the set length, and use that to create a flat index and ng-repeat over the index.
My issue with this is that it doesn't solve the problem of binding to asynchronously-loaded resources. You have to manually implement your own ng-cloak logic, or use ng-bind, to not have {{mustaches}} waiting for data to be loaded.
Compare to Ember, where {{mustache'd}} data-bound bits aren't rendered until their bound variable is defined.
(the, other fix, of course, is to do something like `<span ng-hide="foo != undefined">{{foo}}</span>`, but that doesn't scale particularly well)
Almost all the sites I'll develop take advantage of progressively enhanced components or at minimum, widgets that are bootstrapped server side. Angular wants you to load everything via AJAX - that can get heavy very quickly.
This is also evident within the codebase. You find yourself dancing around DRY violations as you pass models to your markup rendered server side and also serve the same/similar content to Angular via JSON.
Now this aside, Angular wouldn't require much work to let it play an enhancement or migration role. You can already see Google have implement their own 'private' method on the homepage of Angular.
Another problem that grates me about Angular is dynamic routing and loading additional Javascript on the fly. I was recently building a portlet based site. The intention was to make each module entirely configurable by other developers - that meant passing control to their controllers and allow them to enhance routing. As it stands you have to do it declaratively or using some nasty hacks.
I'm surprised that I haven't seen a library for any JavaScript framework that elegantly handles loading JSON returned within a server-side template. It seems like the best of both worlds - use your server-side template, but then also get the data as JSON so that you don't have to do a second request to populate your Angular $scope with data.
The easy way to implement this would be a library that automatically added <script> tags containing the JSON that you could then reference from your Angular template. It could even wrap the JSON in an Angular module of some sort to keep your global namespace from being polluted.
Turns out that using script-tags is somewhat problematic, but as a comment points out, data-attributes could work.
Maybe you can do something cleaner with module.value() ?
I do a simple thing like that for certain settings[0]. I imagine this could easily be done for bootstrapped model data as well.
So you have components server side that need to be in your application. Are they a functional part of the Angular app or just "static" markup that is complimentary to the dynamic pieces?
Worth noting is that unlike other front end frameworks, Angular allows you to have one (or more) elements within a page dedicated as the application container, you don't need the entire page for that.
Front end frameworks such as Angular are certainly geared towards service oriented application development. If that doesn't make sense for your project or architecture, well, square peg round hole situation :-)
I've spent the entire weekend pouring over JS frameworks and have had a rough time trying to compare Angular vs Ember vs Knockout. From a newby, they all seem to be very similar without having written large systems with each to compare.