The Angular Seed's way of organizing a project does not scale well as it organizes javascript files by type instead of grouping the types into different modules [1]. My team has found it successful, especially among new devs, to organize our controllers/services/whatevers in terms of features or areas of concern. This way a new programmer will find the part of the web app she only needs to worry about and ignore the rest. Its a great way of establishing clarity and conforming your code base to the way programmers think about your project.
Another gripe I must bring up with Angular is the lack of proper tools. Batarang has not updated for 7 months and it leaves so much to be desired for debugging with the Angular framework (especially when viewing bindings). Irregardless, these small pains I feel toward Angular are worth trading in the greater pain I feel from Vanilla/Jquery JS development.
We're keeping our code as discreet components, each component has it's own folder in which you'll find the js, html and _scss file for that component only. The js file contains the directive and the controller, and the html is pulled in using require.js' text plugin.
Then the controllers.js file only handles the routing controllers, and the html for each route is built solely out of components.
I resisted using require at first because it seemed like clunky cruft on top of Angular's cruftless dependency injection, but I was wrong and this way of working has been a lot of fun, relatively stress free and great for new devs since they just need to get their head around the way a component is put together and they never have to worry about other parts of the app.
FYI: I just started a new project and decided to go with a slightly different setup that achieves the same thing. I would recommend using the angular-require-seed as a starting point as opposed to the tutorial I suggested earlier.
The credit for this stuff has to go to a guy called Tim Kendrick whom I work with. He set up the project that my project is based on. He figured out the project structure and I've basically copied it with a few minor adjustments.
Then you need an extra module that you inject when you're defining your app. This module is responsible for injecting all the components you want to include, here's a Gist
I'm using Gulp for my build tasks. I can't recommend it enough.
I'm looking into creating a Gulp task that will generate a JSON manifest of components so new components are automagically included in the app. That way there's no need to manually maintain the sass and components.js files.
The first trick requires having the Angular Batarang installed, right? Still cool, I didn't know about that. I've been manually typing angular.element($0).scope() like a sucker.
The 'controllers/directives/services' grouping is straight up moronic.
I build based on features, with all the code and tests of a feature placed together, with any shared dependencies lower down in the directory structure.
> with any shared dependencies lower down in the directory structure
Heh, I'm just imagining code bubble up :P
Though that's definitely a wrong way to think of it since it's a call tree, but it always bugged me that in JS, you'd have to download dependency code you might not use (hence important code "bubbles up"). That's why I'm intrigued to try Dart for it's "tree-shaking" compiler that removes unused code from dependent libraries.
> The 'controllers/directives/services' grouping is straight up moronic
I tend to agree, and this is how I'd organize a larger Angular app, but to be honest I don't think it makes a huge impact in the long run. Rails apps are divided into dirs for models/controllers/views/etc and while I would rather have them organized by feature, they're still easy enough to navigate with modern code editing tools. It's certainly not one of the main contributing factors to how horrible big Rails apps get...
I do it both ways. Major features I pull out into a features folder, but the main skeleton of the app I keep in monolithic controller/directive/services files (or folders if necessary). It encourages me to keep my controllers skinny while providing a place for shared logic to live. It's a good compromise.
I missed out a part of what I do - in order to properly encapsulate and test functionalities within services, they are built out of smaller services that I can test individually, and these get their own directory folders and trees, so long as they are dependencies of an individual service.
I agree with WalterSear that organizing by feature is best. For things that are shared, I like to have a shared/util directory for the miscellania, grouped by purpose (as needed). So, say, if you end up with a few directives used for form validation, you might end up with a util/validation directory somewhere.
The most important question is "can I quickly guess what directory this directory lives in?"
When you come across directives that clearly feel "utility", you will be tempted to look in a utility folder. When a directive is something tightly coupled to a feature, you might be tempted to first look in the directory related to that feature.
Since they won't be used by the main application (ie - app.js, routing, etc, etc), just by features, they bubble up to the root 'features' directory that is contained in the scripts directory.
I forgot to add, I will also create a directory tree for singular service dependencies, so that a service can have multiple, non-shared, dependencies that are each considered a 'feature' and consequently have their own folder containing their code and tests.
I need to blog this, but node is fighting with osX on my macbook right now. I am not a happy camper.
I thought Angular might be cool until my exposure to it consisted of inheriting someone else's project that uses Angular. Digging through HTML looking for ad-hoc HTML tags and wacky HTML attributes was an absolute nightmare. Finding these and then connecting them to the corresponding Angular code, which have the weirdest method signatures, was even worse.
I have a strong suspicion that all of these Angular diehards have never worked on someone else's Angular project.
Admittedly, I do use Angular and I do love it. So take my comment with a grain of salt.
But from my perspective, I'd rather inherit a messy AngularJS project rather than a messy jQuery project. Or Backbone. With jQuery or Backbone, who knows what kind of stack they decided to use, or what kind of crazy hacks they implemented to get it to work? The same thing can happen in AngularJS, but at least it is more probable that they'll be relying on out-of-box tools for core functionality.
Now, I agree that in general, web software front end projects can be gross, but I find Angular to be the least gross solution.
I can understand why you'd think of me as a Angular diehard, but I'm not. I try to choose the best tool for the job, and because of it's structure Angular was the best choice for this project. If Ember or Backbone had been more suited I would just as easily had a love affair with them too!
As for your bad experience, I can see how that can happen with Angular, but I can also see that happening in other ways with other libraries. In my opinion that is solved by using good code patterns and writing code for others, not for yourself. I'll leave this relevant quote:
"Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live." - Martin Golding
Angular, Ember and Backbone are all MVCs. They're more or less different shapes and sizes of a hammer. You'd be missing saws, which can cut through all this, ahem, object oriented crap. And don't forget the simple tools, which can be composed any number of ways and don't make everything look like a nail.
This isn't so much praise for angular as it is for establishing app structure conventions, something that has been around for a long time before angular and has nothing to do with angular itself. Rails is another example of a framework that imposes a specific file/folder structure on all developers which increases consistency across apps (and also coincidentally is quite popular and remained "the hotness" for quite a while in the startup world).
That being said, as I've spent more time programming, I've shifted my preference towards frameworks that don't impose specific structures on you. This is mostly because forcing one structure gives you little flexibility or wiggle room if that structure doesn't fit great with your app, which you can already see other comments here pointing out. If you are working on a project with a team, all you need to do is meet before the project starts and decide on an organizational structure that you are going to use to gain the same results with any framework (and as another comment mentioned, also being able to avoid the fact that angular shoves way way too much logic into the html where it absolutely does not belong, and will quickly get out of hand in larger and/or more complex apps).
Angular most certainly does not establish any app structure conventions. You're thinking of Ember. Angular does, however, enforce other conventions such as modularity and separation of concerns with its dependency injection and directive-based approach to DOM manipulation. That's a very important distinction to make. It strikes the right balance between convention and configuration, IMO.
You've got to be joking. An Angular "module" is a chunk of code that happens to be given a collective name. There's no namespacing, no encapsulation, and no build/file management.
You don't really need to for angular development. Namespacing Javascript is a cargo cult practice brought over from more traditional OO languages.
> no encapsulation
There is if you want it to be. You're especially encouraged to separate the concerns of the DOM in directive services, for example.
> no build/file management
That's kind of up to you, isn't it? You can run with grunt/require if you want a headache, grunt or gulp / uglify if you want easy, you can run with gulp/browserify if you want the new cool ...
I agree that you don't generally need namespacing for JS, but you do need namespacing when everything is referred to by name! If the only way to refer to a controller is that it's called "MainController," with all other information about where it came from and what it does completely lost when it gets added to the registry, then you have to have some way to deal with naming conflicts. Angular... just... doesn't. The Angular injection module is global variables by a different name, and there's no way not to use it. Hell, at least globals you can work around with a no-conflict hack. Compare to Backbone, which is not a perfect framework by any stretch, but with Require it does dependency management and modularization really, really right. Also compare to Java, which similarly forces classes to be referred to by one canonical name, but deals with it via the org.apache.commons... spam.
You're right about services providing encapsulation. I still wind up with a lot of awkward situations where directives can't work without knowing something about their parent scope. It's possible that's more my problem because it's getting less frequent as I abuse ng-model more and more, but also remember that isolate scope, up until very recently, worked in an incomprehensibly stupid way [1].
>grunt or gulp / uglify if you want it easy
Eh... not really that easy. At least, not if you want to anything more sophisticated than concat together every .js file in sight. Require, for all its problems and relative-path headaches, at least makes it dead simple to run in development without having to remember to either add another file to the list or wait for a rebuild every time you change something.
You cannot use two modules that have directives with the same name. Even if you never use them directly, they're only ever dropped in by controller templates as part of what that module does.
When "modules" can break each other because of purely internal implementation details, there is something very wrong.
Huh, I've never come across that before. Yeah, that is a problem, and one that I hope they address soon. Fortunately a workaround exists in the form of naming conventions, tedious as that may be.
So the Angular approach is modular, but slightly broken.
Naming conventions are a workaround in the same way that "remember to free your pointers" is a workaround for the lack of memory management in C, except that managing your own names has no performance benefit.
I really think the whole idea of a global name-based registry is flawed. Again, look at more traditional library/class-based language like Java, C#, and C++ - they have to go to absurd levels of verbosity, and don't even get absolutely guaranteed uniqueness out of it, but the power of dynamic linking makes it worthwhile.
"If you are working on a project with a team, all you need to do is meet before the project starts and decide on an organizational structure that you are going to use to gain the same results with any framework"
If the next step after "decide on a structure" isn't "WRITE IT DOWN", the maintenance devs who follow after you are going to curse your name.
"Most of the time, as soon as you touch the DOM inside your Angular app, Angular will throw a few errors your way..."
"Rightfully so, because I would have destroyed the DOM that Angular was using as its template. Angular doesn't use string-based templates; it uses the DOM itself."
Up until now, string based templates have been far better performing. Using the DOM as a template engine has been clumsy and laced with oddities. (ng-cloak) Not really what it's designed for.
Everything seems to be either written as code (URL handling) or coded into the DOM. Do I really want my HTML to be Angular specific?
I also like this about the article:
"Another way to look at Angular is to give it the sheriff's star in the cowboy land of frontend development. The lack of official documentation and the ever decreasing differences between browser implementations groomed a culture of "whatever gets the job done."
Then he proceeds to write:
"The documentation leaves a lot to be desired, because it's sometimes incomplete or out of sync, leaving the actual source code as the only source of truth. Now this is not cumbersome for an experienced engineer, but it's daunting for a new engineer to even read, much less understand. The Angular source code is not the most straightforward implementation."
You make good points, and I'll try to explain myself as best as I can. (I'm Sean, I wrote this article).
String templates outperform DOM, this was very true in the past and as far as I know still is true. The great advantage of it, is the "live" data bindings, which I think depend on the template being the actual live DOM. (I can be wrong here, and if I am then I need to go learn more about this choice)
As for the documentation point, you are right I contradict myself. What I meant to say is that angular suggests a way to structure your application versus backbone for example that only gives you the tools and no structure.
Thanks for pointing these out, I'll have to be more careful on how I express myself next time I write something.
I dont see how angular suggests a way to structure your application more than backbone did.
In Backbone you had very rigid definitions of models, collections and relationships between them, whereas in Angular any JS object can be a model and relationships between models can also be very flexible(although scope hierarchy is something u need to wrap your head around).
The documentation does leave a lot to be desired and I often find myself going back to the 1.1.5 directive documentation to look up different scope data binding options etc.
Thanks for writing the article. I hadn't considered the design reason to protecting the DOM like this, especially when you consider the core data live binding of Angular. Whether I agree or disagree with the approach, knowing the reasoning behind it helps everything to fit together.
This definitely seems to be the direction everything is going with web-components.
Just to address a point made towards the end of the blog, we do realize that Angular is not a flawless framework, and we are absolutely open to hearing feedback from users of the framework, get your bugs fixed, and ship some elegantly structured, easily testable code.
We are making an effort to do a better job of communicating with our users (apart from the big internal apps). This can be seen in the new Angular community working group, as well as my own and Pawel's frequent activity on the IRC channel and mailing lists. So let us know what your issues are. And if you have time, take a stab at implementing a fix, too. Community contributions are welcome.
Thank you for this very political correct answer. I'll make sure to take you up on your offer to contribute as best as I can, meanwhile can you take a look at our pull request? https://github.com/angular/builtwith.angularjs.org/pull/242
xD (For clarity I'm attempting to be funny in this comment)
While I love Angular, I feel the author is wrong on a few things. It doesn't provide a way to structure your codebase, that's still up to you… directives.js isn't going to scale at all. That's also one of the things I love about angular. The code is modularised, but that isn't enforced on the filesystem. You can choose to lump things into files in a folder for directives, or you can put all your routes, directives, filters etc for each feature in a feature folder. You have plenty of control.
Also, I feel like their example is better served as a filter, rather than a directive.
I agree with you that the structure is still up to the developer, but if you get too creative you'll end up in a mess of code. In this thread other organization approaches have been suggested, that are in my opinion better than the angular seed suggestion. The point I try to make is that Angular when compared to other existing options is more structured. How do you find the balance between flexibility and structure depends on your team and project.
After you wrote about my example, I realize that you are correct, it was not a great one. My bad!
Aside from Square and Groupon, nobody big is building any complex apps around either of these technologies. The question has been and remains: if ember and angular are so great, where are the real use cases?
They're still pretty young, tbh. Most major web companies will probably stick with their existing frameworks, which they are pretty comfortable with by now. Future websites might portray the popularity more accurately.
Nailed it - Angular is horrible IMO. Takes SOOO long to relearn everything then you find some of the inbuilt tags just don't work on mobile or responsively and are difficult to extend. The debugging is a joke too.
Angular is developed by Google and has several developer-celebrities evangelizing it on the web daily, speaking at conferences ever other week, etc. It would be shocking if Angular weren't the most popular framework.
Brilliant point; it's not just that the docs are poor, inherently the framework is so obscure that you need to either be an Angular savant or constantly Googling only to find half the inbuilt functionality cannot be made responsive!
Agree. What set apart a project from another is the quality and amount of documentation, also tutorials, articles, books and reviews(it help a lot on the popularity context).
His are even more skewed, most people don't search for the terms as he's using them. There's also stuff like "backbone js". The only thing I'm proving is that the search trends are really really bad indicator.
The numbers are so small it's hard to draw real conclusions. Outside of hiring new devs with an existing skillset, what's the importance of looking at popularity?
If you're going to have a dependency on a framework, it's nice to have it be actively developed so that you benefit from bug fixes and performance improvements (not to mention community developed framework plugins, extensions or libraries).
A framework gains value from its ecosystem of support. A big advantage of nodejs is all the packages available on npm. With Angular, a big advantage are all the great third-party directives and services (i.e. plugins).
Organizing by feature, while great on the surface, is a challenge when the majority of code is designed for re-use anywhere in the app. As a result, each file is its own module in Plunker. In the WIP rewrite you have modules like "plunker.directive.aceEditor" that will contain a mix of directives and services necessary to interact with the ace editor in the Angular world. In this sense, you could say that code is organized by 'feature' if feature is very narrowly defined.
Understanding a body of code under this approach is relatively simple since the modules required by a given module must be listed for Angular's DI to work. The required modules' names correspond directly to the physical location of the code so navigating is pretty simple.
That being said, there is still lots of room to improve and Plunker is by no means a 'large project' (it is made by a team of 1 person).
I've been building a hobby site for a card game I like to play (http://onosendaicorp.com) in Angular.js over the past few months, just to get a feel for what Angular can (and can't) do. I've found it to be a net positive experience. There are some great ideas in there, and in some ways it saves time over lighter-weight frameworks.
For the record, I've found the documentation to be quite good. Read the guides and understand how it works before you get going, and you'll be able to reason about its behaviour without much trouble. The source is very well documented as well.
nice. The only thing that bother me is that one can feel a huge delay between a click and the actual result of the click on the screen.It is something I feel when using any angular app.
Might be a problem for a LOB that people might use everyday. maybe using read-only bind directives would make apps more responsive.
It certainly feels way more responsive than any non-single-page-app in my experience.
The single page apps I use every day are mostly GWT apps (namely Gmail & co), and comparing those to angular, I'd say angular has the lead (though that's not exactly a fair comparison, maybe GWT could be just as responsive). Don't know how it compares to other frameworks.
Obviously native applications usually still beat web apps in that respect (tho the gap is getting smaller).
The delay is actually related to one of two things (I've profiled pretty heavily)
1. When moving between cards (in the card view), the render is very expensive. The code runs in about 50ms, which could be faster, but is good enough to feel responsive if rendering were not an issue.
2. When searching, laying out the grid is, again, very expensive to render. I've cut out Angular from all except for event handling. The grid items themselves are read-only bound (although the collection watch still exists), and I rearrange their position/visibility through CSS. This is, in my opinion, not a fault of Angular's. The other frameworks wouldn't fair too much better.
Angular has it's ups and downs like every framework.
One of the core issues with angular is maintainability imho. There are few best practices and almost no documentation on proper project layout. You can also build an application any which way you please. Want state in your controller? Sounds good. Want to build an app with nothing but directives? Sure. Inline all your HTML into your directives? yes please. Hell, in theory you could build an entire site out of comments using 'M' type directives. Of course the code base will be a bit of a mess - but it still makes great eye candy.
Another issue with angular is that you're frequently doing a deep dive into how angular is built. Want a recursive directive built in the compile phase? Uh oh, my screen locked up. Pass a '&' scope method into a nested directive? Hmm, does angular wrap that in a getParent()?? Do I need to double bind the parent callback using '=' in the nested call? There is WAY to much need to understand the compile and link phase. My unit tests for $q promises don't fire because they only resolve on a $digest cycle? Uh, how does that work again?
It's a great attempt to build a front end MVC. It definitely speeds up development time and it enforces the IDEA of testing your javascript at a least (a concept foreign to most jquery developers). However, it's still miles from being an ideal front end framework imho.
I am a freelancer and i wanted something simple and clean, so a up for Reactjs and Backbone for most of my projects. Angular is a awesome framework but it just scare me a little bit :).
(sorry for my bad english) I do not want to start an argument about what is better but has everyone saying good things about angularJS here play with durandalJS? To me, coming from a MVVM background, it feels more natural and easier to use. I confess I did not get too far with angular yet so I would love to know what is the opinion of someone who use/test both frameworks.
Another gripe I must bring up with Angular is the lack of proper tools. Batarang has not updated for 7 months and it leaves so much to be desired for debugging with the Angular framework (especially when viewing bindings). Irregardless, these small pains I feel toward Angular are worth trading in the greater pain I feel from Vanilla/Jquery JS development.
[1] http://cliffmeyers.com/blog/2013/4/21/code-organization-angu...