Hacker News new | past | comments | ask | show | jobs | submit login
Coding the Angular Tutorial App in Backbone (42floors.com)
125 points by bernardjhuang on April 16, 2014 | hide | past | favorite | 70 comments



The Angular Tutorial App is an excellent demonstration of Angular's off-the-shelf features. In fact, it's designed precisely to demonstrate Angular's strengths. Angular reduces boilerplate but it's a heavier, more opinionated framework. The price you typically pay for less boilerplate is higher complexity when you need to alter the framework to fit your needs.

This is an extremely common (neccesary?) tradeoff. Think Rails vs. Sinatra or Django vs. Flask. Django gives you a great off-the-shelf backend that's perfectly suitable for most jobs. But I don't want to go under the hood to bend Django to fit an atypical project, and for those I'll use a minimal framework like Flask.

My issue with Angular is that I really want to avoid looking under the hood because the complexity is so high. Backbone is just a small, modular, well-documented library that invites you to look under the hood. If Angular doesn't fit my project, I'm happy to have Backbone in my toolkit, and I know the additional boilerplate up front will pay off down the road. Yes, it'll force me to think more up front about how to organize and architect my app, and that's not a bad thing.


Backbone Marionette would make the LOC comparison a fair one and is worth looking into if you haven't already. Marionette is an especially good answer for people who like the Backbone way of organizing apps but hate boilerplate/non-declarative view bindings.

My favorite part of Marionette is that it has opinions about things like model/view management -- so it avoids a lot of boilerplate -- but it can almost always be molded/tweaked to fit your specific needs (animations, lazy loading, views partially rendered on the server). It lets you 1) mix and match pieces build to work with Backbone (ModelBinder for declarative model-view bindings, Relational for client-side relations, etc.), 2) scale state change management up and down as appropriate for your app (via model changes, controller interactions, route events), and does not force you into a fully single-page architecture if you don't want it.

Anyway, I think Marionette is a pretty great way to write small, modular, readable code without sacrificing high-level abstractions.


> but I’m really fond of the less restrictive nature of Backbone, so I’ll probably end up sticking with Backbone.

Backbone is terribly devious in that it tricks you into thinking that it is unrestrictive and unopinionated. Backbone manages state with mutable models and model change callbacks, so Backbone's opinion naturally is that models and change callbacks are a good way to organize your application. "I want to write hundreds of callbacks to keep everything in sync" said no UI developer ever.


That's sort of a weird way to frame it. I could make the same argument against Angular:

"I want to write a bunch of gross code to perform dirty checking of objects to keep everything in sync" said no UI developer ever.

That's the point of libraries and frameworks. They do the repetitive or "ugly" or "hard" things that we don't want to do over and over.


> "I want to write a bunch of gross code to perform dirty checking of objects to keep everything in sync" said no UI developer ever.

Except that this is in no way an equivalent comparison. With Backbone, you actually have to write the hundreds of callbacks in your application code.

Whereas with Angular, you attach a value to a scope, and declare it in a template. In that case, the framework actually does take care of the 'ugly' for you.

Backbone keeps the ugly in front of your face, it just gives you a slightly neater way to organize it (i.e. as compared to jQuery soup).


My fault. I guess I misunderstood the point being made.


Or you use a templating engine/language and write a simple reusable adaptor. An adaptor you have to write once, assuming one doesn't already exist.


If I'm reading the above comment correctly, the author is stating that Backbone surfaces this to the user. To manage state in a Backbone app requires lots of callback binding.


Huh? I've written quite a few large scale angular apps...and I haven't written a bunch of code to do any of that. If you have something that needs to be checked outside of angular, it belongs in a directive.


The way I see it is you craft those state changes for the objects that need them. You could create a base object that handles basic state changing, too, and just extend from that. On the opposite end of the spectrum, we can make as many assumptions as we like, and override as needed, or we can create an unassumptive mesh of mixins that coordinate and comprise complex objects.

I can do that with a framework that doesn't presume the best path from 0-F. The reason I like Backbone is because it treats me like a developer who knows how to architect an application.


Yes. Backbone basically supplies CRUD mapping and an event bus. So it is opinionated about models.

But CRUD is a solved problem that's easy to implement, and view / controller code ends up being the bulk of your application. I'd rather my framework give me a little help there.

CRUD is even kind of an anti-pattern, because it prevents you from doing relations in your relational database.


> CRUD is even kind of an anti-pattern, because it prevents you from doing relations in your relational database.

Please explain how doing CRUD operations -- which is, after all, what SQL INSERT, SELECT, UPDATE, and DELETE statements are -- prevents you from doing relations in your relational database. Because that's a seriously wierd claim.


I think REST is more accurate, and REST does a shitty job of efficiently expressing relational data.


I know React is backend agnostic, but out of curiosity, what does your ideal server API architecture look like if not RESTful?


I mean REST has its place. For example, it has very predictable performance and well-known cache characteristics. The problem is when you want to fetch data in repeated rounds, or when you want to fetch data that isn't expressed well as a hierarchy (think a graph with cycles -- not uncommon). That's where it breaks down.

I think you can get pretty far with batched REST, but I'd like to see some way to query graphs in an easier way.


I think REST is orthogonal to relational data. (Actual REST, that adheres to HATEOAS and a real REST standard. If one rolls his own JSON services, it's not REST.) HATEOAS puts no constraint on how your data is shaped. A specific implementation of REST may or may not have a nice way to navigate graphs.

[0] http://restcookbook.com/Basics/hateoas/

RESTful Web APIs (2013)[1] is a very, very good book about this stuff. The book has a mailing list with some good discussion about this stuff [2].

[1] http://www.amazon.com/RESTful-Web-APIs-Leonard-Richardson/dp... [2] https://groups.google.com/forum/?fromgroups=#!searchin/colle...

I'm still exploring this stuff myself so maybe I am wrong or misunderstanding you.


How is REST problematic for cyclic graphs? I mean the Web is a graph with many cycles and the Web is the defining instance of a REST application. HATEOAS, a pillar of REST, seems, among other things, to be particularly apt for dealing with arbitrary graphs.


Perhaps they meant an ORM instead of crud.


> CRUD is even kind of an anti-pattern, because it prevents you from doing relations in your relational database.

I'm not sure I get this. How are the two things connected? i.e. why can't CRUD honour relations? (Django's admin does auto-CRUD and handles relationships moderately well - at least to one level of nesting)


Backbone requests return jQuery promises, so you aren't required to use traditional callbacks, but that may be a pedantic distinction. It is also incredibly easy to run all model change events to a global event publisher if that's how you want to bind your logic.


I'm in favor of using whatever framework fits your application the best. I would probably choose Angular if I envisioned hundreds of callbacks in Backbone.


Or just don't use callbacks and observe the model attributes for changes...


A better comparison would be Angular vs Backbone Marionette or vanilla Angular (no pre-built directives) vs backbone. I'm looking at you ng-repeat.

I love angular as much as the next person, but comparing two frameworks by LoC does not do much to move the discussion along.


You can't just take away the pre-built directives as they are a core module of "vanilla Angular" as stated on the front page of the API docs. From controllers (ngController), to models (ngModel), to looping (ngRepeat), to the actual app itself (ngApp), directives are fundamental to using Angular. Taking away core directives would be like taking away selectors from jQuery, or models from backbone; without them, the framework is pretty much useless.


I agree that LoC is rarely the most important factor. It's just what inspired me to actually sit down and code the Angular tutorial in Backbone.


Marionette is terrible. The code is a mess: prototypes defined within instances [0]. Uninformed use of design patterns: controllers are what, just namespaces? [1] Unmodular internals, almost like globals [2].

It's not worth a comparison.

[0] https://github.com/marionettejs/backbone.marionette/blob/mas...

[1] https://github.com/marionettejs/backbone.marionette/blob/mas...

[2] https://github.com/marionettejs/backbone.marionette/blob/mas...


Marionette is a solid framework. It has everything you need to build fast, and clean: regions (which were a great step in the right direction and will be improved in V2), composite/collection views, layouts... the basics are there for you to work with how you would like.

You've made three points which I can't see much fault with. Why the hate?


I'm sorry that you don't see much fault with it. I've tried my best to explain.


I'm sorry but [0] and [1] are complete non-issues and I'm not sure I fully understand your point with [3].

The code is very far from terrible. Go look at Marionette's source on github - you'll find it's extremely easy to understand and reason about. Now try and do the same with Angular or Ember...


How are [0] and [1] non-issues? I like my libraries "SOLID" and "Clean" (look em up). I have worked with Marionette's source, and it's neither.

Point [2] means, to use a different renderer you need to replace Marionette's internal renderer completely like it's a global (globals are bad).


Angular's source is pretty clean, minus compile.js and select.js


try the stickit framework by nytimes, works great for me


Or Angular to EmberJS


I will post this here as well for posterity. I appreciate the time you took to compare and contrast the frameworks and your article is very thorough. We started with backbone on a few large projects and found angular late. We have switched to using angular where ever possible given the reduced code and testability.

I think another good comparison to make that is missing from both demo application stacks is testing. It becomes increasingly difficult to test backbone with the side effects of having jQuery selectors, html elements and general DOM operations directly in your view models. One of the great advantages of angular is it's attempt to make invert your thinking about dom binding compared to other frameworks. Meaning it tries to keep the DOM and the MVVM separated so there aren't unintended side effects if you add or change html node ids or classes. Backbone more tightly couples you to a specific html model and makes testing your javascript code complex and coupled to also looking for changes to the physical DOM during tests.

In the end, the more complex problems see to cause equal headaches in both frameworks, but at least angular give you less lines of headaches.


Man, I'm a bit frustrated with this whole JS situation in recent days. There are so many frameworks, recommendations, hype - it keeps confusing me.

I mean I don't want to spend time learning a framework that might be dead 2 years from now (remember prototype ?). I really don't see a fit for Angular in my practice. However I'm not sure if I'm just saying that because of pure ignorance. Most of my client side code is pretty much jquery (that I try to keep organized), and it works most of the time. Then I see people referring to that practice as "jquery soup" and I'm starting to think I'm doing it wrong.

A lot of the web apps I write consist of pages with ajax sprinkled here and there (where it makes sense). I think a framework like Ember, Angular or Backbone is an overkill in my case. I don't write SPAs, but then again I see people using it everywhere these days.

Honestly, for my scenario I feel that a framework such as Knockout or ReactJs is a lot more "fitting". I'm sure other devs have been where I am, I wonder what you guys think.


> I mean I don't want to spend time learning a framework that might be dead 2 years from now (remember prototype ?)

2 years ago I jumped ship from KnockoutJS to AngularJS. Backbone was also quite hyped out around the same time. All three of them are still around and frankly speaking it wouldn't have been a problem for me if the one I picked died by now. The skills I learned in Knockout helped me quickly learn Angular.

Think of it this way, learning on its own, regardless of what you're learning is valuable. My suggesstion, take a day and examine whatever frameworks you've heard of and pick one and learn it.


> Most of my client side code is pretty much jquery (that I try to keep organized), and it works most of the time. Then I see people referring to that practice as "jquery soup" and I'm starting to think I'm doing it wrong.

Possibly the biggest advantage of Angular is what it does for code organization. With JQuery, you've got to organize it yourself, and while some things are easily organized, others can easily turn into a big mess.

Angular is very big on separation of concerns, modules, dependency injection, etc. Basically, what Angular does, is provide a lot of mature code organization concepts that have been common place on the server-side for ages, to browser-side code. Javascript has long been the domain of little ad-hoc scripts. Stuff like JQuery makes it easier to work with fairly standalone libraries, whereas Angular does for the browser what frameworks like Spring and Wicket did for the server.

Is it what you need? Depends on whether Spring and Wicket are what you need.


xtrumanx said it well. What you learn while picking up any one of these newer frameworks will serve you well.

3 months ago I'd never touched any of them, at least not successfully. Then I got a project to build an app-like mobile website for my company on top of Drupal. I spent a few days trying to figure out how to fake it with jQuery and prefetching, all the while knowing that one of these frameworks was the better way to go. I spent a morning spinning up a couple of JSON feeds in Drupal and the afternoon learning enough Angular to get something to show up on the page, and I think it's fair to say that in the 2 months since that day my developmental worldview (and my productivity) has shifted considerably.

Regardless of how long Angular sticks around (though I suspect it'll be a little while), what I've learned from working with it nonstop for the last 2 months has definitely made me a better developer overall.


The framework battle is really between Backbone, Angular, and Ember. No one else I can think of off hand has the marketshare that those 3 do..

And each has their own strengths and unique opinions. My preference is Ember, but it's just that, a preference.


Even if not writing SPAs, I think frameworks can be great for building pieces of interactivity as cohesive modules. To me, this is a great use case for Backbone or React.


I am currently writing an app in angular and I really enjoy how it supports my workflow. Before choosing angular I did a very thorough evaluation of Javascript Frontend Frameworks. My stomache told me to use backbone because it is simpler to understand the whole codebase and I personally like to know how something works behind the scenes. Also the built with backbone section is pretty impressive. BUT getting started with backbone was not so convenient as in angular. I dont like the fact that I have to extend things and then instantiate them. Also the whole jquery event binding + underscore stuff made me feel as if I was plugging together thousand movable pieces. Angular on the other hand makes your life pretty easy when you stay in the defined boundaries. Angulars has some drawbacks in my opinion: it is very complex behind the scenes (the size alone makes it more difficult to read and understand the source), it doesn't feel like the javascript you know (good or bad?), for almost everything there is a specific angular way.


Yeah, that's one of those things that's hard for people to get at first, that the front-end turned out to be a more difficult problem than writing the back-end.

But people judge an app by its cover, so what can we do.


I made an Ember.JS version of this since we have a few different posts comparing all the frameworks today. Still need to split it up into steps but it's there as an example of the implementation right now

Lines of Javascript: 92

Lines of Javascript(without ember-data model definition): 63

https://github.com/jakecraige/ember-phonecat


I am not a Backbone expert, but telling coding a piece of software with Backbone takes more lines of code than AngularJS doesn't really tell you something.

We could say that a Hello World code in Java is 5 times bigger than in Python, and both has it's pros and cons. Same thing happen with tools and frameworks.


Java and Python are not the same language. AngularJS and Backbone are both Javascript frameworks.

LOC is certainly a useful metric in this case. It doesn't necessarily mean one framework is superior than the other but can and should be used when comparing frameworks.


Java and Python are both General Purpose Programming Languages.

If I had to choose between frameworks, tools or languages. LOC is not the reason why I would choose A or B. Another thing is comparing one of the following: support, active community, features, future improvements, documentation.


> Java and Python are not the same language. AngularJS and Backbone are both Javascript frameworks.

They are, but one of the things that makes Angular so powerful is that it kinda defines its own DSL. Most of your work may not even be in javascript, but in the enhanced HTML that Angular defines for you (and which you can expand by making more directives).


This is really useful and good, esp since the source is on GH. Thanks for putting it together, OP!

That said, lines of code is really the wrong metric to gauge the merits of the frameworks. Fewer lines of code may mean better abstractions, but it also may mean more 'magic'.

A metric that may be more useful would be to have one developer write half the project and have another finish and then compare the time they take to the time they take to do the same project with angular.


I think LOC is actually a great proxy measurement of productivity. 3x the code is 3x the code that can break and 3x the code you have to wade through while debugging or adding features.

I see what you're getting at with "magic" abstractions, but it's like comparing Python and C. I don't know everything that happens under the hood in Python off the top of my head, but I also don't care. I could learn it if I needed to (e.g. needing to use the FFI, or if I find a framework bug). Not knowing is not the same as not being able to know.


The difference here is that in Python vs C, you almost _never_ actually need to know what's going on under the hood[1]. Whereas in every framework I've _ever_ used, I eventually need to dig into the guts of them because of some leaky abstraction. For instance, automatic data bindings are great until you want to do animation[2].

I do agree that LOC for a _non trivial_ application is a reasonable measure, though I disagree that Angular:Backbone is Python:C.

[1]: Serious performance optimization is the exception here, but in building CRUD apps, this honestly did come up infrequently, and usually the right thing to do was to improve algorithmic complexity or fix slow DB queries, not fix python constructs that were unexpectedly slow.

[2]: I haven't spent much time with Angular specifically, but definitely remember this being difficult in other automatically bound frameworks, like Meteor in its initial release.


automatic data bindings for animation are still great though, and its internals should definitely always be hidden from user-land, but I totally agree with you, performance and ease-of-use vary wildly in javascript-land and needs to get better.


There are quite a few places in the code where it appears the author took a longer way around than is necessary, which upped the line count a bit.

An example of this would be restating the DOM tagName on each view instantiation. This appeared to also be done with the className, which didn't appear to change (Although I admit I didn't look particularly hard).

There were some other areas that looked like they could be optimized by removing unnecessary glue. The render function in PhonesFilterView looks to be doing a lot of work to choose the selected option. Unless I'm reading it wrong, you could just pass in this.model.get('sortBy') to the JST and let it do the comparison to select the correct value. Quick value compare instead of a model compare.

I appreciate the work that goes into these types of comparisons, I'm still lead to believe that it shows more about how well you know a framework than it does about the framework itself.

Thanks for posting OP, it was an interesting exercise.


Thanks for the insight. When I first started coding the tutorial I was really trying to minimize line count. I had originally wanted to write a post that said something like "Backbone only takes you 10 more lines of code", because that was what my gut was telling me. But when it became clear that I was not going to be able to get close to the same line count without doing exceptionally weird things, I thought better of it and coded the app like I normally would.

Your point is totally valid about some of the extra stuff I did. The one thing that irked me is that I added some lines because I didn't like the data structure, like the stuff in your example. In real life I would go change the data, but I felt like that might be slippery slope. For example if I changed the data for the phones show view I could have just done a loop over a 10 line template instead of the ridiculously long ~100 line template (although the Angular peeps could have also done the same thing).

In the end I decided to stick with the data provided by Angular and just massage it when necessary. It increased the line count and added complexity, but it made it feel like a Backbone app to me.


One thing this tutorial / thing doesn't highlight is that Angular is ~800 KB (unminified, ~200 KB gzipped, including some modules), versus Backbone's ~60KB (unminified, ~20KB gzipped).

So it does take 240% more lines of code to do sort of the same thing as the angular tutorial, but the angular library is 1000% as big. If my math's correct.

(disclaimer: I like Angular, and for big projects like the one I've worked on, both backbone and angular, I really prefer angular. If bandwidth is a major concern though, and you know how big your app's going to end up, consider library size)


I don't know we're you're getting those numbers - angular is 36k minified, backbone is ~10, and includes much less code (no rendering/binding library etc). Still a nontrivial distance, but a far cry from 700kb/10x


Continuing this point, Backbone requires rendering, binding, and probably relational models libraries. Not to mention the boilerplate and configuration code you have to write to tie all those libraries together. Less may end up being more.

Another point is that with all those libraries, how do you sanely manage the security and quality of your application? With the exception of just a few - almost every Backbone add-on library I've tried is badly programmed (un-SOLID / weird JS / no tests), not documented enough, and unmaintained solo-projects that just so happen to be on GitHub.


There's a big difference: 800k of code that somebody else is maintaining is very likely to be way less hassle than 2.4x the code that you have to maintain.

As a slightly hyperbolic example, imagine comparing code that uses the filesystem with code that directly writes bytes to the disk - sure, it's probably only 5x more code but nobody would seriously entertain doing it...


I dunno. angular is pretty complex.

I'm willing to bet that there's going to be a bug somewhere in that 800kb of code that is truly going to fuck up your day.

At least that 2.4x amount of code _could_ have more straight forward bugs.


Comparing Backbone and Angular is like comparing apples and dinner.

Backbone is a library. You can use it or ignore it, combine it with other stuff, you call Backbone code and use its objects, and it does some limited but well-defined stuff. It's easy to combine with other libraries, and you don't have to use Backbone's feature everywhere if you don't want to.

Angular, on the other hand, is a framework. It shapes everything you do. It bootstraps your application for you, and calls your code when it needs your input. It imposes a totally different way of working and thinking on you. What it does for you is far bigger than what Backbone does for you. It doesn't play nice with libraries that haven't been written for use with Angular.

Really, the difference is like writing a basic Java program where you write the main() and you call some libraries; and using a webframework that handles tons of stuff for you and you just write the controllers, services and views.


I did a similar thing when I was seeking out a MVC framework for my company's JavaScript. I built a page using the same manual JQuery and JS I was using, then I built it with Backbone JS, and finally Angular JS (after learning each one in a tutorial and using TodoMVC as a guide).

Each step I reduced the code size by 50-75%, particularly the boilerplate of tying user interaction events to updating the logical model in JS. Angular's automatic 2-way data binding was definitely the selling point for me on the framework.


After a few months with Angular I find that it shines with complex SPA. Having said that I think everybody should ask himself/herself a question "Do I want a complex app in the first place?"


You can cherry pick examples that make either framework look better. Furthermore, LOC isn't the only factor in framework choice, and it certainly isn't the most important.


Recoding the Angular tutorial is definitely going to favor Angular in parts. There are multiple times in the backbone-phonecat tutuorial where I had to write some code simply to make Backbone work slightly differently, and not necessarily any better. For example, case insensitive ordering.


If I'm working with a RESTful backend API I use Backbone, if not I use Angular. Does anyone use a different criteria?


I can't say I understand why the criteria makes sense. Having used both I can say I don't use Backbone at all anymore. If I'm doing something where SPA makes sense and there will be complex logic on the client side I use Angular. If I just want to enhance what's already there I use jQuery in a components style that's very similar to Bootstrap.

I'll admit I don't really like Backbone much though.


Please fix the URL to "PhoneCat tutorial app" you're pointing to angular.org not angularjs.org


Thanks! Fixed the link. Global replace got me.


Angular is easier for me to read and understand then the equivalent Backbone code right from the start


The backbone app might be more code, but only if you don't count the code used by the libraries.

Angular is probably easier for a lot of people though


They are both probably pretty similar if you count processor instructions.

Point being, having the code be in the library where it is stable, tested, documented, standard, etc is the whole point.




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: