That's not really my experience, nor do I really understand why people seem to say knockout and backbone in the same breath so often.
There is very little overlap in the goals of these two frameworks. The approach is fundamentally different. You could, realistically, even use both in parallel with a few tweaks.
We use knockout in a large scale app (75 person company) and as just a single small component in our stack that really only handles UI bindings and gives our viewModels a bit of structure it's been very solid so far.
We don't use vanilla knockout, we rolled our own data binding and sandboxing. But if you're writing a 'large app' and your architecture doesn't let you swap out components in your stack at will, be it jQuery, knockout, backbone, sammy, without touching anything outside those boundaries then it's not a good sign!
Have to agree here. backbone.js has a learning curve but imo backbone is based on more ideal design principles.
For example the first lesson in this tutorial is telling you to bind data to the view _by manually editing a DOM node_.
Whereas in backbone all your data exists in model objects as it should. Views get initialized/created by view objects, and the bindings are through events. So for the first example, in backbone, I'd use a mustache template to build my view, toss in the model object (obj.attributes) and bind the view rendering to the objects change event. Much more clear lines of responsibility imo.
Thus Backbone.js is definitely advocating much better design principles.
Under the hood those data-bind attributes use the same event model as Backbone views. However unlike Backbone KO doesn't force you to write this event propagation code manually. In KO all I have to do is to declare what property of viewModel I'd like to show up without actually telling about the machinery. This helps quite a bit to reduce code bloat while still giving you all the possibilities of event model. For example one can attach more event listeners to any observable value.
In that 1st example tutorial the author shows bindings directly in HTML because that helps him keep sample code small and demonstrate bindings. Bindings are NOT the major feature of the framework - observables and dependency detection are. However bindings are perfect for demo as they tend to impress the newcomers quickly. They are visually appealing, too. A newcomer sees how little does it take to convert a static markup into a complete dynamic example and is more likely to continue with the tutorial and later try the framework out.
Also note that KO has build-in templates so no one actually forces you to put bindings inside your static (or server-side generated) html. But in general if you don't like having your markup annotated you can get away with pure-js bindings. No one actually stops you from that! The code is a bit more verbose in that case but still comparable to other frameworks.
However I would personally ague in favor if bind declarations inside your markup. Especially in templates that are usually belong to separated visual components or blocks. In practice even though you can put arbitrary JavaScript code inside data-bind values you always gonna have the simplest binding declarations possible: anything bigger than `visible: showItem` would seem unnatural and ugly. So you would define a `dependentObservable` for any computable values or complex conditionals instead. And that's a good thing: code should belong to JS, not HTML. But I would ague that binding declarations are about the same thing as DOM ids and classes: just a list of parameters that help rendering the DOM node correctly. It's not the code.
One thing that Knockout doesn't currently do that Backbone does is helping you structure your application. There are no `Models` in the framework by default although there's a plugin which does fine job. But KO doesn't make structuring you app harder either.
I particularly want to emphasize is that your `ViewModel` is NOT a model and it's not a kitchen sink. I see quite a lot of people who start working with Knockout put all the bindings, all the data, and all the methods into one single gargantuan object. That's not the way things should be organized! It's pretty easy to keep all your entities decoupled and separated. Knockout even has a mechanism to narrow binding context from the parent model to submodels (and access parent model if needed). So, for example, inside your user profile page one can have separate `ViewModel` objects for personal info, contact info, friends list and so on. So, modularity is not forbidden. It's still doable and Knockout doesn't make it hard.
I would ague that writing large structured modular applications is easier with an MVP framework. And it matters very little which framework one has chosen as long as there's one.
One last note: this learning tutorial is focused on current release (1.2.1). The upcoming 1.3 release is very stable and brings some nice little features that make most stuff that I talked about more prominently represented in the framework, more concise and prettier http://blog.stevensanderson.com/2011/08/31/knockout-1-3-0-be...
I'd particularly like to point you to:
- control-flow bindings (that let you keep most templates inlined)
- 'with' binding and bind context switching (helps with sub-viewmodels that I talked about)
- binding providers (helps you keep your HTML data-bind-free)
> Also note that KO has build-in templates so no one
> actually forces you to put bindings inside your static
> (or server-side generated) html.
And that's the problem. Moving bindings out of html starts to make thing ugly, trying to move away to some other templating engine makes them even more ugly and in the end it is just more simple to take Backbone.js and do it all there. It makes no assumptions about your templating engine, your DOM manipulation lib, etc. Not to mention it is smaller few times.
KO is fine if you follow its golden path, but that path is quite narrow.
Thanks for this insight. Having no experience in these new JS frameworks, I'm going to eventually have to choose one, and based on recent HN comments I had almost dismissed Knockout since Backbone is "clearly" better. The points you raised are very informative and now I'm back to looking at Knockout.
I have to say that both frameworks have great supportive communities. As for features here's a very simplified comparison:
Backbone pros:
- eases code structuring with Models and Collections
- gives routing (history management)
- template engine agnostic
Backbone cons:
- Out-of-box UI support is weak.
- Binding plugin is weak
- No automatic dependency detection between the fields (I'm sure there are some external libraries to support that)
Knockout pros:
- first-class dependency detection and event model
- powerful UI bindings (be sure to check out custom bindings - they are very convenient and can make your life a lot easier)
- top-notch templating
- it's believed that MVVM pattern is more suitable for inexperienced developers and eases collaboration in team. My experience confirms that.
Knockout cons:
- No models, doesn't help you with project structure - you're on your own
- Model plugin is there but I can't compare it to Backbone, sorry. It does have synchronization with RESTfull backend.
- Tied to a specific template library. It's possible to integrate other templates with custom providers but I don't know how easy/hard it is.
- No routing support
I picked KO because I believe that framework should do the hardest part and it's ok if the easier parts don't get addressed well. When starting a project I asked myself what would be harder: deal with UI elements or with AJAX. UI seemed harder and Knockout addresses that a lot better than Backbone, so we went with Ko. My team loves it.
Initially when choosing between Ko or BB I made a small experiment trying to tie them up together. It seemed to require a lot of glue code to actually make things work. I guess I haven't been trying hard enough. Someone ultimately got these two frameworks work in sync with this full-featured Backbone-Knockout bridge: http://kmalakoff.github.com/knockback
Looks quite promising although it doesn't seem to have any users at the moment.
I actually like KO better. The additional ViewModel part make organizing the UI code better. The data-bind at the html view location make it easy to see which UI elements have bindings.
Not knocking Knockout.js ;) it's great for really small apps.