Site Meter
 
 

Knockout 1.3.0 Beta Available

iconKnockout version 1.3.0 is coming soon, and it’s going to be a huge release with a big stack of features that many of you have asked for.

The key theme is developer happiness – the new features will let you get more done with less code, eliminate some previous limitations, and offer more power to extend and customize how things work.

New to Knockout? If you’ve never used it before, don’t start with this post – start with the interactive tutorials.

The 1.3 code is now stable and feature-complete, so it’s time for a beta release. You can get it from…

For Visual Studio users, the NuGet package ID is knockoutjs, and this latest version is 1.2.9.0 (reserving version 1.3.0 for the final 1.3 release).

So, what’s new? Well, full documentation for the new features is still to be written, but here’s a brief rundown of the main enhancements.

1. Control flow bindings

Previously, if you wanted to display a repeating sequence of UI elements (“foreach”), or have a section of the DOM exist only if some viewmodel condition was true (“if”), you’d need to create an entire template to define that. A bit cumbersome for something so simple and commonplace! Now you can use the new control flow bindings – if, ifnot, with, and foreach – to achieve basic, declarative control flow without the need for a template. This can make your code a lot more elegant and to-the-point.

Here’s an example of using “foreach” and “if”:

Tip: Switch to the “result” tab to see the output

The "with" binding changes the binding context to whatever object you specify. This makes it easy to compose many independent view models together – you have a host model that contains references to its children, and then use "with" to bind different sections of the page to different child models. Example:

Of course, the "if", "ifnot", "foreach", and "with" bindings can all be combined and nested arbitrarily.

2. Containerless control flow

What if you want to set up template-less control flow (as in the above example), but without having to use extra container elements just to hold the "foreach", "if", etc., bindings? In that case, you can use the new comment-based control flow syntax like this:

The comment-based control flow syntax works with the "if", "ifnot", "foreach", "with", and "template" bindings. In a large number of cases, this means you can skip string-based templates and use the binding-based control flows instead, which can run much faster depending on what exactly you’re doing.

3. Access to parent binding contexts

Whether you’re using regular nested templates, or nesting the new control flow blocks, sometimes you want to reference properties that exist at the upper levels of binding. There are four new pseudo-variables that you can use in any binding (inside or outside traditional templates):

  • $data – returns the current item
  • $parent – returns the item from the parent binding context
  • $parents – an array containing all the parent binding contexts. $parents[0] == $parent, then $parents[1] is the level above that, and so on.
  • $root – returns the item at the top level of binding (usually your primary view model)

Example:

4. jQuery-style event handling

In most cases, data-bind attributes can be kept clean and elegant. But one rough spot in the past has been event handlers, because to pass parameters, you were generally guided to use function literals. For example:

<button data-bind="click: function() { viewModel.items.remove(this) }">Click me</button>

Many of you rightly pointed out that this is pretty ugly. It’s much nicer if bindings can be kept minimal and declarative! To fix this, KO 1.3 lets you replace that with:

<button class="remove-item">Click me</button>

… and then in your JavaScript, add this (if you’re using jQuery):

$(".remove-item").live("click", function() { 
    viewModel.items.remove(ko.dataFor(this));
});

There are two new helper functions that make this possible:

  • ko.dataFor(domElement) – returns the data item associated with a particular DOM element
  • ko.contextFor(domElement) – returns the entire binding context associated with the DOM element, so you can retrieve its $parent property, etc.

Example:

5. Binding providers (and hence external bindings)

Most KO developers find the default data-bind attributes provide a very convenient, easy-to-maintain way of declaratively associating viewmodels with views. But if you would prefer to store your binding configuration elsewhere, the new binding providers API is an extensiblity point that allows alternative configuration mechanisms to be plugged in.

For example, here’s one possible alternative way that you could configure bindings. Notice the absence of data-bind attributes – I’m using a binding provider to set up the binding configuration in JavaScript:

To be clear, binding providers are a general extensibility mechanism, not any specific configuration format. The above example is just one possible way it can be used to define bindings in JavaScript. I’m looking forward to seeing suggestions from the community about how this extensibility can be used, and for what the most elegant and convenient way of defining bindings might be. I know some of you have already suggested externalising bindings (e.g., Brandon Satrom’s knockout.unobtrusive plugin); this new API will make it easier to implement custom binding mechanisms. Bring on more plugins!

6. Throttling

Occasionally, it’s desirable to limit how fast observables and dependent observables update. For example, you might be using a dependentObservable to invoke Ajax requests whenever a set of observables change. Sometimes you might want to change multiple underlying observables, but only have that dependentObservable re-evaluate once, after all the changes (so that it only fires one Ajax request). Effectively, you want a kind of atomic update.

This is now pretty easy to do: you can apply an extender called "throttle" either to observables or to dependent observables. For example:

// Will not notify changes faster than once per 500ms 
var myObservable = ko.observable("initial value").extend({ throttle: 500 });
 
// Will not re-evaluate *or* notify changes faster than once per 500ms 
var myDependentObservable = ko.dependentObservable(function() { 
    // Evaluation logic goes here, usually referencing other observables 
    return 123;
}).extend({ throttle: 500 });

The way this works is that, when throttled, notifications and evaluations are done asynchronously, and don’t occur at all until they stop being triggered for the specified throttle timeout duration.

In the case of making a dependent observable only update once even if there are multiple synchronous changes to its dependencies, you can use a very short timeout (for example, 1ms), and then it will re-evaluate as soon as possible after any series of synchronous changes to its dependencies. Example:

This is all I have time to write about just now, but there are also some other new extensibility features I haven’t mentioned. I’ll follow up with more as soon as I can.

Backward compatibility notes

This beta version of Knockout 1.3 should work with your existing applications, with the following exceptions:

  • It has dropped compatibility with old versions of jquery.tmpl. If you’re using a version of jquery.tmpl older than 1.0.0pre, you’ll need to upgrade. You can find it at https://github.com/jquery/jquery-tmpl.
  • The API for registering custom template engines has changed, so any existing custom ones will need to be updated. The change makes it much easier to define custom view engines (you don’t have to worry about "rewriting" any more). I’ll write a separate post about this soon.
  • Since the binding algorithm has been enhanced in many ways, any third-party plugins that specifically try to alter how bindings work may not work immediately (for example, the "namespaces" plugin). I’ll be talking to the creators of those plugins to ensure both KO and the plugins are updated to work together properly. Apologies for any inconvenience! The new extensibility APIs should make it much easier to implement these kinds of plugins now anyway.

Please try it out and let me know what you think of the new features!

69 Responses to Knockout 1.3.0 Beta Available

  1. Benjamin

    Steve, great update! Looking forward to trying all of these new items.

  2. Jesus Rodriguez (@Foxandxss)

    I updated knockout through NuGet and it uninstalled my jquery tmpl package. I installed the package again (tmpl) (is the same but now I see (beta 1) in the title.

    Now knockout says that need 1.0.0pre or later.

  3. Kai-Rune

    Yes, I’ve been waiting for this update since summer. I’ll try the beta in our projects using Knockout. Thank you!

  4. Steve

    @Foxandxss – That’s correct. As mentioned under “backward compatibility notes”, if you are using jQuery Templates, you’ll need to update it to 1.0.0pre as found at https://github.com/jquery/jquery-tmpl

  5. Fantastic update – loads of great features!

    Annoyingly, I just spent the last three days writing some very complex helpers in MVC to deal with nested view models, that could have been nice and easy with the new ‘with’ keyword. Still, that’s the world of development I suppose.

    Looking forward to the knockoutaddress plugin you demonstrated at Guathon earlier this year. Keep up the good work.

    Cheers.

  6. Jesus Rodriguez (@Foxandxss)

    Oh, I thought that beta was later than pre. My fault.

  7. Luiz

    Excellent tool, congratulations ,
    I think it would be nice to see it working if you publish an crud example putting together asp.net mvc, knockoutjs, EF4.1

  8. Looks SO GREAT. Looking forward to using this, and hopefully converting my team to this.

    On the subject of “containerless control flow,” can we also use it for non-control flow things? I really don’t want to introduce -itis, or templates, just to bind to a property. Something like this would be great, but it doesn’t seem to work:

    http://jsfiddle.net/YDpsX/

  9. Er, that’s “span-itis”; it ate my HTML.

  10. Steve

    Domenic – indeed, a containerless text binding could easily be made to work. You’re not the first to ask for it! Assuming demand for this remains, I’m sure it can be added.

  11. Marcelo

    This looks awesome. I’ll particularly enjoy the new event handlers.

    Is the JavaScript sample for providers correct? Am I missing something because it’s so external? :)

  12. Grahame

    This is an awesome piece of software. I’m looking forward to using it on my next project.

  13. John

    Thanks Steve! You’re the greatest!

  14. 1.3 looks fantastic, Steve! We’ve already been talking about implementing knockout.unobtrusive (http://github.com/bsatrom/knockout.unobtrusive) as a custom binding provider, so these hooks will be fantastic!

  15. Awesome, these are fantastic enhancements. Can’t wait to put them to use!

  16. Does KO work with MVC model binding yet? All the mvc demos I have seen either use ajax to submit, or munge the string fields when submitting normally.

  17. John

    I discovered that I can’t use the control flow bindings within a jquery template. (“This template engine does not support the ‘foreach’ binding within its templates”). Any plans to add this capability?

  18. Great, I think that the new version is a big step.

  19. Keith patton

    All looks great, although I wonder about 4. Should we be encouraging selectors with mvvm JavaScript ? I use Caliburn micro with silverlight, and think that some form of convention with id/class/data-bind attributes would be ideal to provide a commanding equivalent. Otherwise… Jquery selectors pollute the vm with direct view references. In general, id favor more convention in the templates to reduce the need for data-bind attributes as the unobtrusive stuff seems to lean towards, however more acceptable for view to vm binding references than view model to view class or id selector references IMO

  20. Hi Steve!
    Fantastic update!
    KnockoutJS now is a really powerful tool. I hope it will still grow more and more.
    The first point, the “Control flow bindings”, is what I was waiting for.
    Hugs

  21. Steve,

    First let me say, these improvements look awesome! I would strongly recommend that you look at following Semantic Versioning, semver.org, this release isn’t acceptable as a minor step increase to 1.3. This should be a beta of 2.0 because it has backwards compatibility breaking changes.

  22. John

    When I posted above about not being able to use control flow bindings in jquery templates I was thinking that maybe I was unnecessarily holding on to the idea of using jquery templates. Looking through the KO forum I found a link to this fiddle by RP Niemeyer, http://jsfiddle.net/rniemeyer/vky68/8/,
    which demonstrates using an arbitrary html element as a template. So, I think the lights are slowly coming on for me, that I might be able to abandon the practice of using jquery templates in favor of “native” ko templates supported by the native ko template engine. This would be really cool. Can’t wait for more docs!

  23. Steve,
    You absolutely kick ass. I’m going to start using the beta immediately. Sounds absolutely awesome. Thanks!

  24. Thank you, it’s really awesome update!

  25. Mindblowingly good!. Thanks a ton.

  26. Joel Hulen

    Steve, I love the new update! It really resolved a timing issue I had by implementing the new throttling capability. However, I have found an issue with this version that broke some functionality:

    I have a ViewModel containing location information for events. I also have a ViewModel (locationViewModel) that contains the first ViewModel (locationModel) as an observableArray property called locations.

    Now, I’ve got a jQuery template set up that is bound to a div, and within the data binding, I have a foreach declared for my locations property.

    Also within this div, I’ve got another div that is supposed to display if there are no locations. It looks like this:

    No locations have been added.

    I also have a button for adding more locations:

    Add Location

    For debugging, I have another div that displays my underlying ViewModel data:

    ————————————-

    Now, before referencing 1.3 beta, the div would be hidden if I had locations. Also, the debugging information would appear in the other div. That functionality no longer works.

    Also, my button now submits my form, so I set the type to “button” and it does nothing. Before, it was able to call addLocation method of my locationViewModel.

    My template is being properly populated, however.

  27. Joel Hulen

    Sorry about my previous post. It looks like the comments engine stripped out all my HTML tags.

    Let me try again:

    —————————————————

    No locations have been added.

    I also have a button for adding more locations:

    Add Location

    For debugging, I have another div that displays my underlying ViewModel data:

    ————————————-

  28. Joel Hulen

    This is my last try (I promise!)

    —————————————

    div data-bind = “visible: locations().length === 0″
    h3 No locations have been added. / h3
    / div

    I also have a button for adding more locations:

    button data-bind = “click: addLocation” Add Location / button

    For debugging, I have another div that displays my underlying ViewModel data:

    div data-bind = “text: ko.toJSON(locations)”

  29. Alexander Taran

    Do observable arrays have throttle as well?

  30. Michael Flynn

    Thanks alot. This is the best thing since jQuery.

  31. Slawek

    Hi Steve,
    It would be nice if I could use some converter that on binding level – ie. for currency or percents. Also it will be great if Knockout could intergrate with jquery globalize.

  32. Jan

    One more “thank you” from sunny Belarus :)

    We discussed with colleagues this nice engine and thought about another useful thing – what if the engne would has some kind of strong typization for viewModel properties?

    For example if user enters some letter in “integer-typed” textbox, knokout does not allow to do it, does not update dependentObservables and so on?

    Thanx in advance.

  33. I’m beginning to think that, given the foreach binding and friends, there’s almost no need to use jQuery tmpl. Very cool.

    Comment-based control flow is a mistake, however. I don’t want meaningful code inside comments in my HTML. Definitely will be avoiding that particular feature.

  34. Nick Williams

    Thanks for this Steve, looks amazing. I suggested on Brandon’s site (who posted above) about binding providers a little while back – looks like you read my mind!

    Love the inclusion of the $parent vars and the new control flow bindings!

    Now to up another project so i can practice my knockout skills :-)

  35. Nick Williams

    Now to think up another project*

  36. Jon Rimmer

    This all looks really great. The only one I have a problem with is no. 4. I agree that the current approach is a bit ugly, but this solution is a fundamental step backward, in my opinion. The aim of MVVM should be for the view model to know as little as possible about the implementation of the view, certainly not to have event handlers relying on jQuery binds to specific elements!

    What we really need is some clean, declarative way to bind an event to a view model function and supply some parameters, in the same way you use commands and command parameters in WPF/Silverlight to do this.

  37. xLess

    Excelente!, thats very nice, not need to use jtmpl is very cool!

  38. A few requests:

    1.Can parseBindingAttribute raise a warning instead of throwing an error? Currently if the binding fails an error is thrown causing all bindings on following controls to not bind .

    The replacement code would be:
    if( window.console !== undefined) ){
    console.warn(“Unable to parse binding attribute.\nMessage: ” + ex + “;\nAttribute value: ” + attributeText);
    }

    Then we can use the console to view any problems with our bindings.

    2. Currently only the click event allows the shortcut binding (binding to events directly without using the event binding). I realize I can modify eventHandlersWithShortcuts in knockout but I don’t see any value in restricting this to the click event.

    ______________________________________

    Wishlist aside, the is an Awesome framework. I do a lot of complex UI work on a business application and its brought a level of simplicity and maintainability to the code that I didn’t think was possible.

  39. Jeremy Roberts

    When using foreach is there a way to get the index of the current json object?

    I’d like to be able to add a class to every other row in a table to make them stripe.

  40. Jay

    I wanted to try it out for the first time.
    I created an html page with thr required script tags and copied some html codes from the live examples. When I browse it, somehow, nothing shows up on the page. No error messages either. What am I missing? I’d appreciate your help.

  41. Roberto Yudice

    Thank you steve for creating knockout I would be crazy already if I had to use backbonejs verbose shit.

  42. Thank you for Knockout, ive just started to work with it, and its good..
    Please do something with $(“.elem”).live…, I think that’s not good (cant explain why but its not) :)
    some sort of event handlings inside knockout will be nice… bind, trigger…

    thanks

  43. How about adding a “data” binding to models?

    This would be equivalent to

  44. How about adding a “data” binding to models?

    <div data-bind=”data: {id: id, name: name}”>

    This would be equivalent to

    <div data-bind=”attr: {‘data-id’: id, ‘data-name’: name}”>

  45. zhangbenrong

    Hi steve
    Thank u for your great work.
    I like control flow binding and pseudo-variables ,its usefull.

  46. Dan

    All I really want in the next version of Knockout is a built-in REST client. This thing would be a backbone killer if it I didn’t have to roll my own data access layer.

  47. Chris

    I love the Containerless control flow but I’m seeing it only works some of the time, depending on where it is placed. For example this does NOT work.

    ko comment tag with if

    tr tag
    end tr tag

    end ko comment tag

    But this does

    tr
    ko comment tag if
    td tag
    end td tag
    end ko comment tag
    end tr tag

    Not sure why but it would be nice if it worked no matter where it exists in the markup.

  48. Chris

    Great library. Absolutely brilliant really.

    Complex UI layouts can be a challenge though. Being a novice Knockout practitioner it took me about 3 or 4 days of on/off effort to finally get the layout I was looking for. Well, I would have liked to figure out how to accomplish this without tables but that was going nowhere fast.

    Here’s a link to the finished result: http://jsfiddle.net/cmschick/hyHQW/

  49. Any reason why data-bind=”if: level() > 1″ is not allowed?

  50. Jay

    Any status on the 1.3 release? I’m very interested in using the latest, but my company does not allow beta software in the environment. Please advise.

    Thanks

  51. Hi Steve,

    Just wanted to let you know that I love KnockoutJS, and i have been playing with 1.3 lately and loving the new features. One problem I am encountering is that whenever I use “foreach” or “if” on a page that has templates (the old way of using them), the new bindings do not seem to work, I have to switch them to templates in order to get them working, any ideas?

    Thanks!

    Jose

  52. Name *

    There’s lag generating a table for an array of 89 objects and data-binding text, attr, click for four properties. When filtering, it’s faster to hide rows that aren’t related than to use a filtered dependentObservable.

  53. Name *

    Why is this slow? It takes 10 seconds to load for me. How could this run faster? http://jsfiddle.net/pYjet/9/

  54. Andreas Kroll

    Hi Steve!

    Great news that knockout 1.3 is in ReleaseCandidate state. I’m really looking forward to working with it, and some of the new features will make it a lot easier.

    One thing I was wondering about in your example “control flow binding” was:

    If you use the “if:” to check on attribute values, and the attribute is missing, the complete block vanished.

    If you remove the manufacturer attribute at the item “banana” instead of setting it to “null”, the item banana does not get displayed at all.

    Could “if:” just work as if the attribute value was “null” if the attribute is not available at all?

    This would really be useful if you work with differently structured data.

    Thanks
    Andreas

  55. Andreas Kroll

    HI Steve!

    If you change the binding line to

    it all works well.
    But it would be really nice if the “if:” binding would itself check for availability, if possible.

    Thanks
    Andreas

  56. Andreas Kroll

    Ok, another try to display the tags:

    <em data-bind=”if: typeof(manufacturer) != ‘undefined’ && manufacturer”&gt:

  57. Any reason this version isn’t highlighted on KnockoutJS.com? It makes it hard for people to find it.

  58. zbrong

    Hi steven
    we are waiting for to release the 1.3 version.
    your are great !

  59. Pingback: Developer Forums » EntitySpaces, Punchout, and Knockout 1.3 » Developer Forums

  60. Pingback: EntitySpaces, Punchout, and Knockout 1.3 | Code to Preload

  61. Love the new version. Just got done playing with the new features and they work as advertised. The best MVVM simple lightweight framework for javascript just got better! Cant wait to see more intergration into ASP.NET MVC 4 come up with better Html Helpers and seamless validation propagation from the server to the web occur similar to this but baked in http://pastie.org/private/aufxr4pyvwj2jqixngkppg (this is using FluentMVC stuff changed to fit Knockout).

  62. Pingback: EventArgs - A Web Development Blog

  63. Makoto

    Steven,

    First of all, I just wanted to say what a great asset Knockout has been and I can’t imagine life without.

    I’m using the latest version from GitHub and one thing that no longer works with templates is the ability to use this syntax:

    {{each(index,item) Items}}
    #
    {{/each}}

    I’d like to be able to tell what index each item is within the collection.

    Is there a way to do that in the new data-bind=”foreach:Items” syntax?

  64. Hung Vu

    Your awesome library knocked my mind out! I really love not to use jquery.tmpl.js. Throtling, binding provider are big improvements (IMHO). Thanks so much.

  65. Frank

    I’ve a problem with the binding provider
    example
    the example posted in this post give me an error:

    Uncaught TypeError: Cannot call method ‘conventions’ of undefined

    Why?

    Thanks

  66. szilardd

    @Frank: you have to include the koBindingConventionsPrototype2.js file. You can find it here:

    http://jshost.googlecode.com/hg/koBindingConventionsPrototype2.js

  67. Praxiss

    Just finishing off a huge project with knockout at its core. Can’t wait to remove all those jquery templates and replace with the built in template engine

    Great work on this, will post a link to the project when it goes live and let you guys have a peek