Using AngularJS at Localytics
localytics.com
localytics.com
1) If you have a new project, I would go with Angular (or even Ember if you are from a Rails stack)
2) If you want to refactor an existing one, check Backbone, it might be a bit less causing a rewrite rather than a refactor
My tips if you still choose backbone:
- learn it first inside and out, spend at least 2 days doing any tutorial out there, even if it's a few dollars (code school, peepcode, tutsplus etc)
- make sure you learn 1.0, older examples might be confusing
- read the backbonejs.org documentation from start to end, and read the annotated source, especially read the FAQs and also read the github issues, jashkenas (the author) is sometimes responding himself
- I tried to avoid any plugins at first (no Marionette, deep model, BB-relational etc) if you see you need too many plugins, just ask youself if it's worth it, you might want to give Angular (or even Ember) a chance. I found out that for anything that looks hard, there is a way to do it in Backbone the "backbone way"
- Last: remember that Backbone is simply helping you get code from the form of document on load God function with tons of event listeners, that trigger ajax calls, that trigger dom manipulation, to about the same code, but in models and views, so you can make sense of all of it, that's all.
Yes, you need to clean up your listeners, and when using the 1.0 listenTo and stopListening (which are automatically called when you remove a view or destroy a model) then you are going to be ok with the zombies.
Backbone taught me a lot of JavaScript, it was more perhaps harder than Angular but the code is readable to anyone without even learning backbone, it just makes sense
so don't expect Backbone to do any magic, it doesn't, but it is still a very relevant and valuable utility library, and I think it's a must have step in any front end developer's life to do at least one BB app before moving to Ember or Angular (just my humble opinion)
And if you're struggling to ramp up on Angular, I would recommend sticking it out. The learning curve is steep (or is that gradual?--I never understood this analogy), but once it clicks, your productivity will go through the roof. Angular has redefined what I mean when I say "rapid prototyping."
<a href=”#” onclick=”doSomething()”>
Then we realized it was bad to couple presentation and behavior, so we made our Javascript unobtrusive, keeping our templates clean. But now we’re back at it again, writing <a href=”” ng-click=”doSomething()”>.
Have we learned nothing?---
This seems like a good point that I can't refute - anyone?
<a href="#" id="show-help-link">Show Help</a>
<script src="text/javascript">
$("#show-help-link").click(function() { showHelp(); } );
</script>
And <a href="#" ng-click="showHelp()">Show Help</a>
I mean, HTML has behavior in it. A link in itself is "behavior": when you click this tag, go to the page defined in the src attribute. So, as the author says, it's not really a bad thing that templates have behavior in them. In Ember.js, for example, you have an {{action}} handler that is essentially the same as ng-click - "run a function on the controller when this is clicked."Oh, and, you can use $('#show-help-link').click(showHelp); instead of click(function() { showHelp(); }); ! : )
<a id="clickable-link">
And the putting something like the following into a js file: $('#clickable-link).doSomething()
I find the declarative markup of a well-written angular app to be quite clean and easy to read, much more so than the alternatives.Having a "onClickButtonA()" function call bound to a button whose id is "A", and then have the logic associated to the click on that button somewhere in the controller is a completely different thing than having "checkAccountBalanceAndSubmit()" directly in the HTML.
Angular remove 80% of explicit HTML/javascript conversation that were only there to dumbly synchronize input views and model. The rest is just really unavoidable.
The second one not HTML at all, rather it is written in an XML-like configuration language which declaratively specifies the structure of the view, in which the attributes use Angular's JavaScript-like expression DSL to declaratively specify how its elements are bound to the behaviors available on whatever controller has been injected into this template. This allows you (or a non-coding designer) to completely change up the connections, appearance or structure of the view while touching no JavaScript whatsoever.
So in this case the markup and the behavior can be intimate, without actually coupling; thus there is no need for anxiety.
We're building webapps - there's going to be behaviour attached to dom nodes. You could use a class instead but in my experience you end up in a worse place. When people do it as classes (or data attributes / whatever else) someone is going to come along and wire styles to those. You'll just end up with a much more twisted coupling of behaviour and presentation. I've unpicked this mess more times than I care to think about right now.
Also, it's really different in Angular - the behaviour is not as coupled. Each element has its own scope - the old "bad" way was wiring up html elements to GLOBAL scope. That's obviously not great.
Edit: so I don't sound so snarky.
HTML already has a bunch of behaviors embedded in it. Links, styles, dropdown menus, input fields, radio boxes, etc. The angular devs are simply embracing the declarative nature of HTML and extending its available behaviors. In that respect, angular is actually treating HTML more like it was intended to be treated.
And I agree with the OP's lamentations about the javascript being completely divorced from the HTML. You end up with code that is so decoupled it's a major undertaking for someone new to your project to figure out what's going on. In an angular.js app, all they need do is look at the HTML and they can get a good idea what's supposed to be happening and where.
edit: And the truth is, jQuery apps aren't polluting the HTML any more than Angular apps, they're just doing it in the form of additional CSS classes and IDs and "data" attributes. In that respect, you could say that jQuery pollutes the css declarations.
With custom attributes there is no confusion, and although it goes completely against the separation of concerns and now your mark-up isn't completely declarative -- it's a necessary drawback.
pBlue bWidget?
I've never done this, just wondering.
But parentheses try to lookalike the onevent attributes, which a) everybody doesn't like and b) immediately invoke javascript code
In AngularJS point b) can't be the truth - there is for sure some layer of expression evaluation, and that is what disturbing - as an experienced javascript developer you know that this layer exists, but you can't easily see what happens inside that layer - AngularJS hides that from you.
In most cases in traditional JS development - nothing really happens in this layer, it's just a dumb method invocation in the context of the view and has dom event as a single argument - this is clearly visible in libs such as Backbone.
But in Angular this layer of expression parsing and evaluation does exist - and you don't know what kind of magic happens there and how thick, maintainable and overridable this layer is. This possibility of dirty magic - that really disturbs me in all the simple tutorials of AngularJS, so I don't have courage yet to give it a try in a serious project.
For documents.
Applications are not documents.
ng-click="doSomething()" runs doSomething() in the scope of the controller that contains the element. Good!
My team was at a similar crossroads a few months back when trying to decide which javascript framework to pick for our mobile app. It came down to Backbone, Angular, and CanJS (because we had previously used JavascriptMVC on a project). It really came down to Backbone vs. Angular and we were leaning heavily towards Backbone. We all built demos using each of the three frameworks.
I was the Angular advocate and after having experienced incredible joy creating my demo I was desperate to get the rest of the team on board. After much debate we were leaning towards backbone, until that is, I asked "how would you go about making sure your views are updated and your forms validated". After we walked through the work that would be needed to be done maintaining the view state in real-time on a backbone app, and a few other examples like retrieval of form data or validation of forms, it became clear we'd need to write a lot more DOM manipulation glue-code using Backbone than we would with Angular.
In the end, this was what pushed us over to the Angular side. The focus on testing and the dependency injection throughout was another huge selling point for us. And frankly, it wasn't clear to us how a Backbone app should be structured. In fact, that variability appeared to be one of the main selling points of the framework but it ended up paralyzing us with choice. Being first time Backbone developers we weren't sure we could ever feel confident knowing we were following best practices.
The blog author's problem was a brief bug that was introduced and fixed between releases for the rare use case when a data-bound view is re-rendered. We fixed this problem and the author confirmed that the patch was "working great."
https://github.com/NYTimes/backbone.stickit/issues/66
So even though the problem was fixed for the blog author before he moved onto angular, he still claims that stickit causes memory problems. I guess a false claim like that makes the story of moving to a new framework more entertaining.
Another claim from the blog author is that stickit makes it hard to use third-party plugins like Chosen. Around the same time he filed the github issue, we were finishing and getting ready to release "handlers" and a new "initialize" binding which give you the ability to create global handlers for setting these kinds of bindings up. More on handlers here:
http://nytimes.github.io/backbone.stickit/#custom-handlers
... and an example of setting up a global handler for Chosen:
The Closure ecosystem has their own templates (soy) which are compiled in Advance Mode (with renaming) by the Closure Compiler. It's not possible to do that with Angular attribute's which reference JS names.
See this conversation about Angular support in Closure: https://groups.google.com/forum/#!msg/angular/hePiqQA-MCI/uT...
Here's a particularly useful sample app, implemented in both Angular as well as Backbone.
http://coenraets.org/blog/2012/02/sample-application-with-an...
Directives are, IMO, the most powerful parts of angular. They're also the most confusing. OP makes a great suggestion here that I'd recommend as well: Start with a normal template & controller then refactor into a directive later. In my experience, I've found that it's been useful to focus less on the DOM manipulation that needs to take place and more on the where the data collected needs to flow. In this way the directive just becomes the "glue" between a tiny area of the DOM and a parent controller and/or scope.
I guess you could liken them to the behavior/logic you'd have in a backbone view? That may be a stretch though. Powerful nonetheless.
- Directives : I'm no JS ninja so even after those egghead.io I'm still lost, but it gets better !
- jQuery : Angular kinda want to kill it whereas I think it should play nicer with it, especially for plugins. AngularUI jQuery Passthrough (or custom directives) should not be necessary IMO.
- Expressions : they are powerful but there is almost no documentation about them and I feel like an idiot sometimes. Thank god for Stack Overflow ... (where in the Angular doc can I learn that I can do ng-click="[action_1, action_n]" ?).
- Views helpers are usually put in the controller. That doesn't seem the best approach, or maybe people put them in a service and inject it in the scope from the controller ?
- Providing initial data : I usually put data in javascript variables and get them in the controller and assign them to services or the scope. Is there a better way ?
I have the same experience. I also tend to do the occasional DOM manipulation from the controller, using jQuery. I know it's frowned upon in the Angular community, but it at least allows me to experiment and, as the quote implies, figure out what I want before I know exactly what I need.
That being said, I'm starting to use directives more and more, and they are certainly a powerful tool that cannot be ignored if you are going to build an Angular app.
[edit] spelling
Dealing with deeply nested views can still be a bit of a headache, but I prefer the extra control over view rendering that I get with Backbone vs. soem other frameworks (I have no experience with Angular).
I get the feeling that their form re-rendering headaches had to do with parent views that were listening to unnecessary events, like a collection view that listens to individual model events.
it works , i like the DI stuff though i always used my little lib for that before( https://github.com/Mparaiso/Pimple.js ) .the 'dirty checking' always felt like a hack , i'm glad Google is working on it with Object.observe. as for the code inside the html, since it is a "scoped" eval with its own dsl it's fine.
But i still use backbone especially for games and non dom related apps.
what matters is choice , and angular is still light weight compared to beasts like Sencha.