
Knockout: JS library for rich UIs, declarative bindings, and dependency tracking - stevensanderson
http://knockoutjs.com/
======
jluxenberg
FYI, in case you were wondering as I was, whether it is legal to add arbitrary
properties to HTML tags:

 _"The data-bind attribute isn’t native to HTML, though it is perfectly OK
(it’s strictly compliant in HTML 5, and causes no problems with HTML 4 even
though a validator will point out that it’s an unrecognized attribute)."_

------
vmind
It's good to see more developments in this area, as I liked the management
offered by projects such as SproutCore, but the stack as a whole was very
heavyweight.

I did work on my own take, using some of the ideas from SproutCore, though
didn't get very far in polish (<http://github.com/erudites/eventful>)

I've only had a brief look, but the dependency tracking looks much cleaner
than other solutions I've seen for partial template redrawing.

Do Backbone and Knockout interact well, or are there conflicts in getting them
to play nicely together?

~~~
equark
There's a fair amount of overlap between them, so I'm not sure you'd want to
use both. Backbone has a more integrated persistence layer, but that layer is
pretty tied to the model. It wouldn't make sense to use that and use Knockout
for the view. There may be some useful cross-pollination, but that should just
be by both frameworks adding/changing features.

------
csomar
This is really awesome. It's lightweight, well documented and Open source.

I actually find it better to use Backbone, jQuery and Knockout together
instead of heavy and bloated libraries like ExtJs and Cappuccino. These three
libraries provides the necessary functionalities to build a medium sized
JavaScript application. You'll have to take care of the design yourself,
though.

~~~
martinkallstrom
Would you give a brief description of how Backbone and Knockout fit together?

~~~
csomar
I didn't go throughout the frameworks, but I imagine this scenario:

Backbone is the main platform. You'll use it for pretty much everything except
one thing "templating". Knockout will fit well with templating. The example
that is present in the home page is what I think of. This will help separate
the two processes. I'll have two different files reducing the complexity of
each one. jQuery is the rescue when dealing with other DOM issues, animation
and also AJAX.

------
AlexC04
WOW! :) Automatic refresh? I can't tell you the number of times I've had to
abandon fancy Ajax because of the need to refresh the DOM (checkboxes that
were 'deleted' still existed in the form submission... yes I'm sure there's a
way to do it, but there's a balance between time and ... oh nevermind)

Also, I really like the way that bindings are done.

data-bind="click: foo();"

is so much nicer than

$(':checked').each(function(bar){/* do foo; */}).bind(this);

or whatever it was I was doing in jQuery the other day. I'm probably mixing up
my prototype and jquery syntax there. :)

~~~
drivebyacct2
If you want this, you should check out the new data binding in jQuery. It
enables it in a cleaner fashion (no JS in HTML attributes) and accomplishes
the same goal.

------
n8agrin
Sorry to lead with a criticism but the use of the data- attribute in these
examples is kind of ugly. I understand their motives, but if you're going to
use data- in a "declarative" way, why not just have multiple declarations of
the data- attributes? For example: data-bind-value="firstName" data-bind-
text="firstName", etc. I'm sure I'm missing something.

That said, this looks like an interesting library and worth playing around
with. I'm loving the huge amount of JS framework experimentation going on.

------
raganwald
Serves me right. I do an essay about MVC, PVC, and (¬M)VC patterns, and
someone comes along and introduces the very interesting MV(VM) pattern. Very
interesting!

~~~
jashkenas
Obligatory MVVM Pattern Wiki link:

<http://en.wikipedia.org/wiki/Model_View_ViewModel>

~~~
raganwald
Interesting. The primary motivation as expressed in that link seems to be the
separation of concerns to facilitate having a specialist UX designer and a
specialist programmer working in a decoupled way.

~~~
equark
My experience is that this happens only after the view has matured. It's hard
to foresee everything that should be in the view model. The UX guy will want
certain things in the API and there will be a lot of interplay between the two
roles to start. The advantage is that once the model has matured, the UX guy
has a lot of flexibility. Refactoring the UX is pretty independent of the view
model. The view model also tends to be more robust because it's easy to unit
test, unlike some jQuery mashup.

------
scotth
Very nice.

I'm disappointed to see JavaScript back in attributes though. Can the bindings
be defined programmatically?

~~~
jashkenas
It's also calling eval() on every single data-bind attribute you have:

[http://github.com/SteveSanderson/knockout/blob/master/src/bi...](http://github.com/SteveSanderson/knockout/blob/master/src/binding/bindingAttributeSyntax.js#L7-14)

Perhaps Steve can comment on how well this performs in real-world views with
thousands of DOM elements...

~~~
stevensanderson
The evaling is a robust way to parse the JSON-like binding syntax at the full
speed of the browser's native code. Much faster than implementing the parsing
in JavaScript.

~~~
jashkenas
Just to be clear -- the "JSON-like binding syntax" includes arbitrary
JavaScript code, right? That's how stuff like this works...

    
    
        <button data-bind="click: function() { allItems.sort() }, enable: allItems().length > 1">
          Sort
        </button>

~~~
stevensanderson
It can do in cases where you find that more convenient. Whenever you prefer to
move logic into your view model and just reference it, you can do so. It's
intended to be flexible.

------
wildmXranat
I would consider removing the background image located:
<http://knockoutjs.com/img/main-background.jpg>

It takes almost 4 seconds to load and delays the site's rendering. Making it
load much quicker is really the goal here. Also, it's 3000 x 2227 pixels
large.

~~~
saurabh
Looks sweet though.

------
jonpaul
I think this is huge. I say this coming from working with MVVM in .NET/WPF for
the last year. I've worked with Javascript (ExtJS) before, but I always found
it a pain in the ass to use.

MVVM promotes testing, while allowing developers to build simplistic and
decoupled apps. I for one am pumped to have found this!

~~~
equark
This testing point is spot on. Last night, I was getting killed with little
bugs on some dynamic menu / tab widget where things got added and deleted and
the active tab needed to move around smartly. Knockout allowed me to whip up
30 tests for the expected behavior and then make sure my view model worked
correctly and had a decent API before turning to the actual view. With just a
few commands I could bind this to the view and all the functionality worked
flawlessly.

------
STHayden
as a designer this still seems a little convoluted to me. I think jquery did
so well because of it's simple interface and I think javascript mvc can also
be done simpler then this.

I'm not saying this is bad. Just that I'm not going to jump on this until a
simpler option come around. I am also a mvc fan.

~~~
equark
I would try it. I'm using KnockoutJS plus CoffeeScript and it's hard to
imagine how it could be much cleaner. I would never go back to using jQuery
bindings for UI except maybe for the smallest little things.

~~~
eterps
Could you give an example how KnockoutJS and CoffeeScript fit together? Or is
there a blog post somewhere that explains the details for using this combo?

------
pistoriusp
Is this similar to backbone.js?

~~~
jashkenas
They're two very different approaches to the same problem. To put it roughly:
Backbone emphasizes smart models that can be passed around and observed by
views or controllers, and Knockout emphasizes smart views that have bindings
and logic written into HTML attributes.

The levels of granularity are also different. With Knockout, any change to the
data will update that atomic portion of the view. With Backbone, the default
is to be much more coarsely grained. The good baseline approach for getting
started is to simply re-render the view when the model changes:

    
    
        model.bind("change", this.render);
    

And now, whenever _any_ attribute in the model is updated, the view is
redrawn. In most cases, that's all you ever need, but in performance critical
cases, you can optimize by listening for changes to specific values, and
updating just those portions of the view.

    
    
        model.bind("change:title", function(model, newTitle) {
          titleEl.text(newTitle);
        });
    

It's great to see different approaches to JS Apps start to surface. I wonder
how much cross-pollination there's going to be...

~~~
equark
I considered both Backbone and Knockout and ended up with Knockout, although
both are great! I find Knockout's simple declarative binding to be cleaner for
most cases:

    
    
      <span data-bind:"text: title"></span>
    

And Knockout allows you to put bindings in code too, where that makes sense. I
also like the way Knockout keeps everything in the view model, rather than
passing in the observable attributes when constructing an instance. For
instance:

    
    
      var Sidebar = Backbone.Model.extend({
        promptColor: function() {
          var cssColor = prompt("Please enter a CSS color:");
          this.set({color: cssColor});
        }
      });
    

Here color doesn't exist yet. I guess this is just standard javascript style?
In Knockout (+coffeescript), I'd write:

    
    
      class SideBar
        color: ko.observable('white')
        promptColor: ->
           @color(prompt('Please enter CSS color:'))
    

My model is self-contained. This example also shows the syntax for updating
and getting values. I prefer Knockout's

    
    
      @color(cssColor)
    

to Backbone's

@set({color: cssColor})

although this is minor and perhaps you want to allow for bulk updates.

I can't help but feel that these types of libraries are the future. I hope
there is lots of cross-pollination going on. Sproutcore focuses on the 5
percent of webapps that should be desktop style. Both Knockout and Backbone
give lots of the same benefits, but allow a more flexible application style.

My only wish is for a language agnostic persistence protocol, with some
socket.io and REST protocols implemented for most frameworks/languages.
Ideally, I could use this protocol to sync with my iPhone/Android/HTML5 app,
without changing the server side. This could get very hairy
(FeedSync/LiveMesh/Wave), but something simple that accomplishes 90% would be
a great.

------
rafaelferreira
Wondering how Knockout data binding compares to Flapjax. I find the idea of
bringing FRP to the browser promising, but Flapjax' choice of either a js
preprocessor or a cumbersome API put me off.

------
JustAGeek
Just chiming in to say that the website for knockoutjs is extremely well done,
congrats!

Example right on the homepage, clear communication what it does, great list of
examples on the other pages - way to go! :)

~~~
bkudria
Seconded.

It helps to that the example is super-simple and easy to understand.

------
dpatru
Seems similar to Microsoft's JQuery plugin: <http://api.jquery.com/link/>.

------
po
Can someone familiar with this project please explain how this infers the
dependencies in the procedural code that you write?

~~~
stevensanderson
See
[http://knockoutjs.com/documentation/observables.html#how_dep...](http://knockoutjs.com/documentation/observables.html#how_dependency_tracking_works)

------
CarlHoerberg
I hooked it up with WebSockets and got a very nice real time collaborative web
app in a few lines of code: <http://github.com/carlhoerberg/knockout-
websocket-example>

------
viggity
Schweet! I love declarative bindings, it is hard for me to think in any other
fashion after working in WPF/Silverlight for the past 3 years.

I'm excited to play around with this

------
Tycho
This will be very useful, great work.

