Knockout makes it easier to create rich, responsive UIs with JavaScript

Overview

Knockout

Knockout is a JavaScript MVVM (a modern variant of MVC) library that makes it easier to create rich, desktop-like user interfaces with JavaScript and HTML. It uses observers to make your UI automatically stay in sync with an underlying data model, along with a powerful and extensible set of declarative bindings to enable productive development.

Getting started

Join the chat at https://gitter.im/knockout/knockout

Totally new to Knockout? The most fun place to start is the online interactive tutorials.

For more details, see

Downloading Knockout

You can download released versions of Knockout from the project's website.

For Node.js developers, Knockout is also available from npm - just run npm install knockout.

Building Knockout from sources

If you prefer to build the library yourself:

  1. Clone the repo from GitHub

    git clone https://github.com/knockout/knockout.git
    cd knockout
  2. Acquire build dependencies.

    Make sure you have Node.js and Java installed on your workstation. These are only needed to build Knockout from sources. Knockout itself has no dependency on Node.js or Java once it is built (it works with any server technology or none). Now run:

    npm install
  3. Run the build tool

    npm run grunt

    Now you'll find the built files in build/output/.

    To run a single task, use --

    npm run grunt -- build:debug

Running the tests

If you have phantomjs installed, then the grunt script will automatically run the specification suite and report its results.

Or, if you want to run the specs in a browser (e.g., for debugging), simply open spec/runner.html in your browser.

License

MIT license - http://www.opensource.org/licenses/mit-license.php

Comments
  • Components and custom elements

    Components and custom elements

    We're typically quite conservative about adding significant new features to Knockout core, since we highly value keeping it as a small focused library, and not a big heavy framework.

    This is good, but web development in 2014 as a whole is now converging on a newer way of building applications. Inspired by future standards including Web Components (with HTML imports and custom elements), plus experimental libraries such as Polymer.js, you can see that developers will soon want and expect to build highly modular applications, composed from reusable encapsulated pieces, with extremely clean markup.

    Knockout in 2014

    How should Knockout.js respond? One possible response would be to do nothing, and say that people targetting really new browsers can find their own ways of combining those new standards with KO. Possibly using polyfills, even though it's hard work. But if we do that then I think the relevance of Knockout will decline.

    A different response, which I favour, is to embrace this direction and provide really first-class support for 2014-style web development in Knockout by means of a few carefully-chosen core features.

    And among all the major JavaScript libraries, Knockout is probably the only one that can deliver this in a way that works seamlessly right back to IE 6, because KO already has exceptional backward compatibility.

    Proposed new features

    I've given this a fair bit of thought and built some prototypes, and here are the three interrelated features that I think are sufficient and necessary:

    1. Components - an easy way for your view to asynchronously pull in separate things that encapsulate their own viewmodel and view
    2. Custom elements - a simple and satisfying syntax for referencing components without all the data-bind
    3. Text interpolation - a.k.a., {{ curly }} expressions inside text and element attributes

    These things don't turn Knockout into a framework - it's still a library - but they are hugely flexible tools that encourage and support more modular architectures.

    Prototype: More about this later, but if you're impatient, here it is.

    Components

    A component is a combination of view and viewmodel. You register a component with some name before you can use it:

    ko.components.register("cart-summary", {
        template: ..., // Element name, or source URL, or a function that asynchronously returns a node array,
        viewModel: ... // Object, or AMD module name, or a function that asynchronously returns an object
    })
    

    Now you wouldn't often use the component binding directly (since you'd probably use a custom element instead - see below), but if you wanted to:

    <!-- ko component: { name: "cart-summary", data: someData } --><!-- /ko -->
    

    Of course, that looks ugly, hence the custom elements feature below. But what this does is pass the someData value to the template and viewModel callbacks for the component, then when it's got the results, renders the template with the viewmodel. Simple, but also powerful.

    Implementation

    This is pretty much just a variation on the template binding, except it supports retrieving both a view and a viewmodel asynchronously before it renders. We could even implement it by extending template, but I suspect it might be cleaner to keep it separate.

    Custom elements

    For a nice way of consuming a component, use custom elements:

    <cart-summary user="{{ currentUser }}" max-items="10"></cart-summary>
    

    Given that you've registered a component named cart-summary, this just works. The data value it passes to the underlying component in this case is { user: currentUser, maxItems: 10 }.

    And here's the whole point of this: now your application doesn't have to be a monolith any more. Instead of one master viewmodel that is directly coupled to child viewmodels which are directly coupled to more child viewmodels, i.e., a monolith, you can now instead have many completely independent viewmodels that have no knowledge of each other, and exchange data only via custom elements in their views.

    This makes code easier to reason about, and pieces easier to reuse. And if people build really general-purpose components (grids, etc.), they can be packaged as independent open source projects.

    Implementation

    In case you're wondering about the {{ ... }} syntax, and how it's possible for components to know when the values change (and write back changes) even if they aren't just observable instances, well that actually works out quite nicely. KO knows when evaluating them whether they have any dependencies, and hence might change in the future, and in that case can wrap the accessors in writable computeds. Sounds complex but the result is that it just does what you'd want and expect.

    Text interpolation

    This is way overdue. In a sense it's separate from components and custom elements, but the lack of this feature in core is kind of embarassing already.

    It just means this:

    <a data-bind="attr: { href: '/items/' + id() }">
        See also: <span data-bind="text: name"></span>
    </a>
    

    ... can be written:

    <a href="/items/{{ id }}">See also: {{ name }}</a>
    

    That's a bit better :)

    Having this just means that all your components' views become not annoying at all. It does not eliminate data-bind; it just makes it unnecessary for inserting text and setting simple, write-only attributes.

    Implementation

    We could already do this easily as a node preprocessor. However since this involves walking the text inside every attribute inside every element, performance is pretty vital. We probably want to be sure that we only go looking for the curly braces once per DOM fragment, not every time the same DOM fragment is inserted into the document (e.g., in a foreach). Maybe this fits into "template rewriting", but I haven't actually dug into this yet. I'd be especially interested in whether @mbest has ideas for making this super-fast.

    And BTW - the curly braces used for custom element parameters would be implemented separately, because on custom elements you're not just assigning attributes.

    A prototype

    I've spiked up rough versions of components and custom elements here: https://github.com/SteveSanderson/ko-custom-elems-test/. There's a live demo too, though the end result is not as interesting as the code.

    This proof-of-concept includes:

    • Incremental loading. When you first arrive, it only loads code related to what's on the screen. As you navigate around, it automatically pulls in any additional JS/HTML needed for what you're seeing. This is thanks to components supporting asynchronous loading. The actual JS-file-loading works via require.js in this demo, but you could also use any other way of fetching viewmodels.
    • Routing via crossroads.js. I'm not proposing this somehow becomes part of KO; I'm just showing it works cleanly with components.
    • Browser support right back to IE 6, even with all the custom elements

    For some of the APIs, I've put in a lot of thought already. For other APIs, it's pretty arbitrary. All of the implementation is rough. No doubt we (and especially Michael) can come up with more streamlined implementations.

    This prototype does not yet include text interpolation. It would be easy to add it in a simple way, but I'm interested in nailing the performance on that first.

    Why not a plugin?

    We could totally do this as a plugin. That might even be a good way to start.

    However, the goal here is not just to provide some new features that some people might like. It's about aligning the Knockout project with the direction of the industry as a whole, making the core library relevant and appealing to web developers in the coming years.

    Feedback requested

    Please let me know what you think!

    Please try to keep replies focused on the features described here. For discussion of any other possible features (or existing bugs, etc.), many other great GitHub issues are available :)

    type: meta 
    opened by SteveSanderson 74
  • feature request: add afterRender event for knockout components

    feature request: add afterRender event for knockout components

    Hello,

    I propose to add an afterRender event to components binding - the event to be fired after viewModel and template are loaded and bound. Event will be useful for example to make area visible after component is loaded.

    Best regards

    severity: minor type: feature affected: most api 
    opened by SuperCuke 69
  • 2.1 release discussion

    2.1 release discussion

    I went through all the open issues and selected 14 of them to include in 2.1. I've divided them using labels into bugs (3), documentation changes (2), enhancements (8), and cosmetic changes (1). I've also divided the code (non documentation) changes by impact: minor (8) and moderate (4). All but three of the issues already have code attached (some I just added today) or don't involve code changes.

    opened by mbest 63
  • Release version 3.4.0

    Release version 3.4.0

    Steps to release:

    • [x] Run tests on supported browsers and fix any failing tests.
    • [x] Update documentation with new features (see #1873)
    • [x] Write release notes.
    • [x] Publish release candidate.
    • [x] Respond to any urgent bugs.
    • [x] Build and create release in Github.
      • [x] Update doc site with latest version.
    • [x] Publish to NPM (@mbest)
    • [x] Publish to NuGet (@SteveSanderson).
    • [x] Post on Google groups, blogs, etc. about new release.
    type: meta 
    opened by mbest 61
  • New feature: communication to components

    New feature: communication to components

    It is possible to get components to communicate with a host vm by passing a callback function to the component via the `params`` binding, so the component is able talk to the host.

    There is no feature to be able to invoke methods on the vm that I have seen. At present I pass observable values to the component and get the component vm to subscribe to these when it needs to know of events in the host.

    severity: major type: feature affected: average api 
    opened by conficient 59
  • Status of knockout

    Status of knockout

    Guys, what happened with this project? There are a lot of open issues and PRs. Also, what does Waiting to hear about 3b2dab6 means? It points to a 404 @ http://www.clahub.com/agreements/knockout/knockout

    Best wishes!

    @SteveSanderson replying your last comment on the other issue, know that I'll be happy to provide any help you guys may need. I just would like to be more into what's going on since I was a bit away from this project in particular.

    type: meta 
    opened by heyvito 49
  • May/June/July v3.2 planning

    May/June/July v3.2 planning

    Recently we've focused on adding some major new features (components, custom elements, pure computeds), which is great - but people won't be using them until they are released :) So let's work towards a v3.2 release.

    Perhaps we could aim to have the release out at the start of July. That gives us about 6 weeks for remaining improvements and documentation.

    Features

    • [ ] Consider whether or not we can implement string interpolation ({{ value }} syntax) in native DOM templates.
      • We'd only want to do this for 3.2 if it was fairly straightforwards. @mbest, you probably have the best overview on likely implementation details - what do you think?

    Bugs

    • [ ] Whatever we have time for, from the top of the triage list, particularly those rated 45+.
      • I can certainly take out a few of those. @mbest / @rniemeyer - are there any you're keen to handle and would have capacity for?

    Docs

    • [x] Components
    • [x] Custom elements
    • [ ] Pure computeds

    Anything I missed? Do you think the timeline is reasonable?

    type: meta 
    opened by SteveSanderson 46
  • Add support of filters/projections for observableArrays

    Add support of filters/projections for observableArrays

    A common scenario where experience from usage of KnockoutJS can be improved is having an observableArray of elements that is not binded directly to HTML, but first projected to a set different items, or filtered by a condition.

    Would be great to have something similar to:

    var array = ko.observableArray([]); var filtered = array.filter(function(item) { /* condition / }); var projection = array.select(function(item) { / selector */ });

    Right now you can achieve this by using a computed observable, but this will mean that every item of resulting array will be tested against condition/selector if any item of initial collection changes, and thus whole array will be rebound, that is not effective in terms of performance. The fact of recreation is itself crucial as it may result in the loss of state for items that were recreated, in the case it was a projection.

    opened by estrizhok 44
  • Include Typescript types inside repository

    Include Typescript types inside repository

    Hi wonderful knockout team !

    I wrote precise TypeScript types definitions for knockout. Definitions can be found here: https://github.com/typed-contrib/knockout/blob/master/global/index.d.ts

    This project was written for the typings which is shutting down leaving me with two solutions:

    1. Merge my definitions with DefinitelyTyped types.
    2. Merge my definitions directly inside the source project.

    I prefer the second solution because it avoids having multiple dependencies in NPM. Indeed, TypeScript compiler automatically finds types which are included in NPM packages.

    Do you agree to include these types? If you do, I can open a PR to make the appropriate configuration for you.

    Thank you very much for this library which I really make huge use! You can find most of my knockout related open-source projects here

    opened by SomaticIT 41
  • Is this project still alive ?

    Is this project still alive ?

    I really like this project very much, but I'm a bit concerned about the fact that there are still many (old) opened issues, and it seems it's no longer actively maintained. My main concern is related to the usage of this library into a couple of big projects I'm going to start this year. My customers are raising questions about the potential impact caused by the usage of abandoned / not evolving dependencies. Are there future plans and evolutions for this project in the foreseeable future ? Is there the realistic possibility that the significant amount of opened issues (at least the bugs) are closed in the near future ? Thankyou for you answer :)

    opened by NinjaCross 40
  • 2.2 release discussion

    2.2 release discussion

    I'd like to get the ball rolling on version 2.2. I just finished going through all the open issues. 36 of them I closed, mostly invalid, already fixed, or duplicates. 48 of them I have marked for inclusion in 2.2. Just like for 2.1, I've also divided them based on "impact" and whether they're "bugs" or "enhancements". In addition, I marked some issues for version 2.3+ and a few as "future".

    I also set up a 2.2 milestone to track our progress.

    opened by mbest 40
  • docs: Fix a few typos

    docs: Fix a few typos

    There are small typos in:

    • spec/asyncBehaviors.js
    • spec/defaultBindings/valueBehaviors.js
    • spec/mappingHelperBehaviors.js
    • src/binding/defaultBindings/textInput.js

    Fixes:

    • Should read reserved rather than resever.
    • Should read keystroke rather than keystoke.
    • Should read initialise rather than initalise.
    • Should read happens rather than happends.

    Semi-automated pull request generated by https://github.com/timgates42/meticulous/blob/master/docs/NOTE.md

    opened by timgates42 0
  • Only run visible/hidden binding once on init

    Only run visible/hidden binding once on init

    I'd like to run the default hidden KO binding once when knockout renders my template. According to the documentation you can pass in a non-observable as the first param and updates should no longer be applied if the model value changes.

    Looking at the code here https://github.com/knockout/knockout/blob/master/src/binding/defaultBindings/visibleHidden.js I don't think that is the case.

    Please can someone advise how I can invoke the hidden and visible handlers only once and ignore future updates to the model?

    Thanks

    opened by josh08h 1
  • Plan of support for knockout.js

    Plan of support for knockout.js

    This is more of a tech-audit issue than a functional issue: What sort of timeline do the contributors to knockout.js expect to support it?

    I ask because the issues are not readily adjudicated and we are a few months away from the 10 year anniversary of an issue of an unsupported dependency: https://github.com/knockout/knockout/issues/788

    opened by jaredtait 3
  • Templates don't work with SVG

    Templates don't work with SVG

    See: http://jsfiddle.net/gburca/hwb92esf/33/

    The generated HTML looks identical, yet the 1st SVG drawing is not displaying the circles (even though they're in the generated HTML). The 2nd drawing (which doesn't use templates) displays them properly.

    opened by gburca 2
Releases(v3.5.1)
  • v3.5.1(Nov 5, 2019)

    This release fixes a few regression bugs in 3.5.0:

    • Empty template with if option throws an error #2446
    • IE error from inserting a node before itself #2450
    • Problem with initial value binding on <select> when the options are generated via a foreach binding #2452
    • Missing arrayChange notifications when using deferred updates #2454
    • Template binding removes <script> template contents #2484

    3.5.1 also fixes some issues with and expands 3.5.0's TypeScript definitions.

    Source code(tar.gz)
    Source code(zip)
    knockout-3.5.1.debug.js(310.68 KB)
    knockout-3.5.1.js(66.64 KB)
  • v3.5.0(Feb 22, 2019)

    Knockout 3.5.0 includes a few new bindings and new ways to interact with observables and bindings. The full list is detailed under 3.5.0 Beta, 3.5.0 RC, and 3.5.0 RC2.

    The final 3.5.0 release includes fixes for a few regressions in the pre-production releases:

    • Fix performance issue with nested if bindings (#2414)
    • Fix exception with foreach and beforeRemove (#2419)
    • Fix misplaced nodes with foreach and Punches plugin (#2433)
    • Fix duplicated nodes with foreach and if (#2439)
    Source code(tar.gz)
    Source code(zip)
    knockout-3.5.0.debug.js(309.00 KB)
    knockout-3.5.0.js(66.35 KB)
  • v3.5.0-rc2(Sep 8, 2018)

    This release includes a number of fixes for regressions in the previous 3.5.0 release candidate. Given the time since the RC, we also decided to include a few small improvements.

    • Fix to maintain an element's focus when it's moved by the foreach binding.
    • Fix changes to style binding to correctly append px.
    • Fix regression to ko.contextFor when used after ko.applyBindingsToNode.
    • Revert changes in ko.utils to use native array methods.
    • Remove global createChildContextWithAs option and add noChildContext binding option. The default behavior for as matches previous releases.
    • Fix the interaction of descendantsComplete and if/ifnot/with bindings.
    • Add an option for if/ifnot/with bindings: completeOn: "render" will have the binding wait to trigger descendantsComplete until it is rendered.
    • Throw an error for unbalanced virtual elements.
    • ko.applyBindings throws an error if a non-Node is given as the second parameter.
    • Support an options objects as a parameter to createChildContext.
    • Support a custom rate-limit function as the method parameter to the rateLimit extender.
    • Support setting custom CSS properties with the style binding.
    • Optimize how many elements are moved by foreach.
    • Update TypeScript declarations.

    We decided to keep the more standard return value for ko.utils.arrayFirst, which now returns undefined instead of null when no item matches.

    Source code(tar.gz)
    Source code(zip)
    knockout-3.5.0rc2.debug.js(306.83 KB)
    knockout-3.5.0rc2.js(65.88 KB)
  • v3.5.0-rc(Apr 26, 2018)

  • v3.5.0-beta(Dec 29, 2017)

    Knockout 3.5.0 beta release notes

    Full list of issues: https://github.com/knockout/knockout/milestone/9?closed=1

    Important: This release includes some minor breaking changes to the foreach binding to improve performance and clarify features. These changes can be turned off using global options.

    • When using the as option with the foreach binding, Knockout will set the named value for each item in the array but won't create a child context. In other words, when using as, you will have to use the named value in bindings: text: item.property rather than text: property. This can be controlled by setting ko.options.createChildContextWithAs = true. (See #907)

    • To improve performance when array changes are from a known, single operation, such as push, the foreach binding no longer filters out destroyed items by default. To turn this off and filter out destroyed items, you can set includeDestroyed: false in the foreach binding or set ko.options.foreachHidesDestroyed = true to use the previous behavior by default. (See #2324)

    Other enhancements

    • You can react to the completion of bindings such as if and with using the new childrenComplete binding or subscribing to the childrenComplete binding event. (See #2310)
    • You can react to the completion of components, including nested components, by including a koDescendantsComplete method in the component viewmodel or subscribing to the descendantsComplete binding event. (See #2319)
    • Binding strings can include template literals (backticks) and C++ and C-style comments.
    • Observable arrays include sorted and reversed methods that return a modified copy of the array. This is in contrast to sort and reverse that modify the array itself.
    • The new class binding supports dynamic class strings. This allows you to use the css and class bindings together to support both methods of setting CSS classes.
    • The new using binding, similarly to with, binds its descendant elements in the context of the child viewmodel. Unlike with, which re-renders its contents when the viewmodel changes, using will just trigger each descendant binding to update.
    • The new hidden binding works oppositely to visible.
    • The new let binding allows you to set values that can be used in all descendant element bindings, regardless of context.
    • Similarly to let, you can set such values at the root context by providing a function as the third parameter to ko.applyBindings. (See #2024)
    • Performance improvement: String templates are no longer parsed each time they are referenced. Instead the parsed nodes are cached and cloned.
    • Observables notify a new spectate event whenever their value changes. Unlike the standard change event, this new event isn't necessarily delayed by rate-limiting or deferred updates. You can subscribe to the event without waking a sleeping pure computed; the computed will notify the event if it is accessed with a new value.
    • Computed observables include a getDependencies method that returns an array of the observables that the computed is currently watching.
    • The attr binding supports namespaced attributes such as xlink:href in svg elements.
    • The ko.when function allows you to run code once when an observable or condition becomes true.
    • The ko.isObservableArray function can be used to check if something is a ko.observableArray.
    • The style binding will use jQuery if present. Even without jQuery, the binding now supports standard style names, such as background-color, and automatically appends px if needed to styles that expect it.
    • Knockout will throw an error if it finds an unmatched closing virtual element (<!--/ko-->).

    Fixes

    30 or so separate fixes are included in this release,

    Source code(tar.gz)
    Source code(zip)
    knockout-3.5.0beta.debug.js(304.17 KB)
    knockout-3.5.0beta.js(65.29 KB)
  • v3.4.2(Mar 6, 2017)

    This release fixes a number of bugs related to deferred updates and computed observables.

    • stop infinite loop from dirty events in circular computeds (#1943)
    • only update a computed if dependency has actually changed; not if it was just dirty (#2174)
    • only notify subscriptions that exist when a change occurs; don't notify future subscribers (#2163)
    • notify dependent computed of change in reverted observable if the computed previously read a different intermediate value (#1835)
    • update a pure computed if a dependency has changed and notification is pending (#2197)
    Source code(tar.gz)
    Source code(zip)
    knockout-3.4.2.debug.js(282.80 KB)
    knockout-3.4.2.js(58.93 KB)
  • v3.4.1(Nov 8, 2016)

  • v3.4.0(Nov 17, 2015)

    New features and bug fixes

    • Improves performance of components, templates, computeds, and observables.
    • Includes a native version of deferred updates, along with a microtask queue (ko.tasks).
    • Calls a ko.onError handler, if defined, for errors from asynchronous code.
    • ko.options.useOnlyNativeEvents can be set to tell Knockout to use only native (not jQuery) events.
    • Includes ko.isPureComputed().

    The 3.4.0 RC release notes has the full list of issues and pull requests included in this release. The final release fixes two regression bugs found in the RC:

    • #1903 - New beforeRemove behavior can break retained items.
    • #1905 - Endless recursion possible with ko.computed.

    Possible compatibility issues

    1. Components now use microtasks to perform updates asynchronously instead of setTimeout. Since microtasks are run before the browser repaints the page, all loaded components will be initialized and displayed in a single repaint. Although this reduces the overall time needed to display components, it could result in a longer delay before anything is displayed.
    2. The new, native deferred updates feature has a slightly different API and is implemented differently than the Deferred Updates plugin. Migrating from the plugin will generally require some code changes (full details to come soon).
    3. ko.observable and ko.computed no longer use a closure when defining their methods, such as dispose and valueHasMutated. These functions expect this to be set correctly and so can't be used directly as a callback. Instead you'll need to use bind, such as obs.dispose.bind(obs).
    Source code(tar.gz)
    Source code(zip)
    knockout-3.4.0.debug.js(279.99 KB)
    knockout-3.4.0.js(58.41 KB)
  • v3.4.0-rc(Oct 12, 2015)

    Knockout 3.4.0rc release notes

    Enhancements

    • #1715 - Add ko.onError handler that provides more consistent error/stack information for async operations and event handlers
    • #1728 - Include deferred updates functionality in Knockout core
      • #1738 - Deferred Updates 1 - ko tasks functionality; deferred extender for enabling deferred Updates
      • #1753 - Deferred Updates 2 - add ability to turn on deferred updates globally by setting ko.options.deferUpdates = true;
      • #1795 - Deferred Updates 3 - dependency tree scheduling
    • #1774 - Add ko.options.useOnlyNativeEvents (default false) that can control if KO uses jQuery (if available) for binding events
    • #1839 - Performance Improvement - for named templates that use a template or normal element use the element directly as the template to clone
    • #1840 - Performance Improvement - Make observables 2-3x faster to instantiate and reduce memory usage by 50%
    • #1841 - Performance Improvement - Make computeds 2x faster to instantiate and reduce memory usage by 50%
    • #1870 - Add ko.isPureComputed.

    Fixes

    • #1256 - Better handling when an item is added while a beforeRemove animation is running
    • #1380 - observableArray sort and reverse methods now return the observableArray rather than the underlying array
    • #1510 - Do not define a custom element when a component name matches a standard element
    • #1591 - Make checked binding work properly with writable computed observables
    • #1613 - IE8 issue with calling .apply with an empty second argument
    • #1683 - Rearrange code to avoid prototype issue in Opera mobile
    • #1709 - dontLimitMoves option should be respected when comparing arrays
    • #1718 - ko.toJS no longer replaces RegExp objects with plain objects
    • #1756 - Use a hasOwnProperty check when registering components
    • #1781 - Trim string in default css binding
    • #1783 - Skip template elements when binding
    • #1788 - Fix textInput edge case in IE9
    • #1790 - Remove version from bower.json and don't update it in build
    • #1794 - Exception in an afterAdd callback should not cause duplicate elements
    • #1810 - Don't check for require for CommonJS
    • #1855 - Fix potential memory leak in component binding
    • #1893 - hasFocus fixes in IE
    Source code(tar.gz)
    Source code(zip)
    knockout-3.4.0rc.debug.js(285.33 KB)
    knockout-3.4.0rc.js(58.52 KB)
  • v3.3.0(Feb 18, 2015)

    Enhancements

    #1504 - Component configuration can specify a synchronous option to render already loaded components synchronously. #1463 - Component child elements are provided to the createViewModel method, component child elements are exposed on the binding context as $componentTemplateNodes, and the template binding can accept an array of DOM nodes directly through the nodes option. #1449 - Binding context now contains a $component property that references the nearest component view model (allows for easily binding to the root of the current component). #1596 - Create a writable computed within a custom element component when an expression evaluates to an observable (less need to use .$raw property). #1576 - computed observables (pure or deferred) notify an awake event with the current value when awakening, pure computeds notify an asleep event with an undefined value when going to sleep, and the getSubscriptionsCount method on an observable can accept an event name argument to return only the count of subscriptions for that event. #1543 - Sleeping pure computed observables now cache their value. #1635 - Export ko.utils.setTextContent #1427 - Export ko.dependencyDetection.ignore as ko.ignoreDependencies

    Fixes

    #1321 - Ensure that template nodes are created and moved within the correct document to fix cross-window issues in IE. #1434 - Binding parser skips all colons between the name and value. Support returning malformed bindings (non key-value pairs). #1468 - css binding was not clearing a previously added dynamic class when the value bound against changes to null. #1507 - Memory leak fix for foreach/template binding #1513 - Fix error in fixUpContinuousNodeArray when using jquery.tmpl #1515 - Update dependentObservable._latestValue when a pureComputed wakes up (affects debug build only) #1526 - Component's require option should not try to do an AMD-style require in a CommonJS scenario. #1556 - Check that the value passed to optionsAfterRender is a function before calling #1597 - CSS binding now works properly with SVG elements #1606 - Don't bind contents of <textarea> elements #1623 - When using valueAllowUnset: true, null selection should be maintained when option items are updated. #1634 - Better clean-up of arrayChange subscriptions

    Source code(tar.gz)
    Source code(zip)
    knockout-3.3.0.debug.js(263.60 KB)
    knockout-3.3.0.js(54.64 KB)
  • v3.3.0-alpha(Nov 13, 2014)

  • v3.2.0(Aug 12, 2014)

    Knockout 3.2.0 release notes

    Enhancements

    • 1290 - Components infrastructure and binding. Reusable, extensible components that can dynamically combine a view model and template. Component documentation
    • 1385 - Custom elements as a way to consume components (example: <my-component params="value: price, format: priceFormat"></my-component>). Custom element documentation
    • 1359 - ko.pureComputed - a computed that sleeps when it has no dependencies. Pure computed documentation
    • 1160 - Added textInput binding for robust handling of real-time updates (key presses, pasting, drag-and-drop, etc.) to a field as an alternative to value binding with valueUpdate options. textInput documentation
    • 1146 - Make the value binding act like checkedValue when used on same element as checked binding.
    • 1039 - Bower support now includes distributable (built) files (3.1.0 release was also updated to include these files).

    Fixes

    • 1334 - Fixed an issue with the value binding when used with afterkeydown and rateLimit.
    • 972 - Fixed handling of 0 in style binding.
    • 1252 - Fixed ko.utils.postJson truncation issue.
    • 1433 - Make template/foreach work with an observable name option.
    Source code(tar.gz)
    Source code(zip)
    knockout-3.2.0.debug.js(254.73 KB)
    knockout-3.2.0.js(52.86 KB)
  • v3.2.0-alpha(Jun 19, 2014)

  • v3.1.0(Mar 4, 2014)

    This release focuses mainly on performance and stability/compatibility improvements, plus small enhancements to existing functionality (yes, we're saving the big new features for v3.2). So, in 3.1:

    New features

    • #1190 - new rate limiting functionality to have better control and flexibility over throttle/debounce scenarios
    • #1003 - renderTemplate now supports the name argument being observable.
    • #647 - add valueAllowUnset option that allows the value binding to accept a selected value that is not currently in the list of options
    • #627 - provide access to dependency count and whether it is the first evaluation within a computed
    • #1151 - provide item index to array util method callbacks
    • #1272 - deferred computeds will now be evaluated on a manual subscription, if not previously evaluated
    • #865 - ko.utils.domNodeDisposal.cleanExternalData extensibility point can be overriden (perhaps to prevent jQuery.cleanData from being called in some scenarios)

    Perf improvements

    • #775 - in browsers that support setting proto, set subscribable/observable/computed/observableArray prototype rather than copy methods from "fn" objects.
    • #1221 - use objects instead of arrays to track computed dependencies (can be major perf boost in older IE when there are lots of dependencies on a single computed/observable).
    • #1199 - various performance optimizations related to array operations

    Bugs fixed

    • #844 - prevent older IE errors with options binding used in separate document
    • #1081 - prevent option placeholder from being re-added in update
    • #1191 - remove jQuery workaround related to checked binding when using newer jQuery versions.
    • #1193 - look for jQuery instance in ko.applyBindings, if it was not available when KO was loaded. This helps to prevent issues with KO not taking advantage of jQuery, if it was not loaded before KO.
    • #1206 - for observable view models, $rawData should be the observable
    • #1207 - "arrayChange" tracking no longer assumes all items added are new on a splice
    • #1208 - older IE issue with options binding related to optionsCaption being removed on each update
    • #1209 - prevent a deferred computed that is disposed before evaluation from taking dependencies when evaluated
    • #1214 - prevent errors when using the value binding with jQuery templates
    • #1255 - track observables accessed in getBindingAccessors - helps backwards compatibility with custom binding providers
    • #1289 - prevent adding a disposal callback when disposeWhenNodeIsRemoved value is not a node
    • #1306 - value binding - fix issue related to autocomplete tracking always firing update in browsers that don't fire change event on autocomplete
    Source code(tar.gz)
    Source code(zip)
    knockout-3.1.0.debug.js(214.75 KB)
    knockout-3.1.0.js(46.19 KB)
  • v3.1.0beta(Feb 12, 2014)

  • v3.0.0(Oct 25, 2013)

  • v3.0.0rc(Sep 30, 2013)

    Changes since 3.0.0beta:

    • Addition of arrayChange event for ko.observableArray and trackArrayChanges extender for adding this functionality to any observable.
    • Support binding to detached nodes.
    • Support arrays of observables.
    • Computed observables notify only when their value changes, using the same logic as regular observables. Use the notify extender to have a computed always notify.
    • optionsCaption sets value as text instead of HTML
    Source code(tar.gz)
    Source code(zip)
    knockout-3.0.0rc.debug.js(205.79 KB)
    knockout-3.0.0rc.js(45.07 KB)
  • v3.0.0beta(Jul 8, 2013)

    1. Independent bindings: When an element has more than one binding, such as visible: showPlaylist, template: 'playlistTmpl', each binding is updated in a separate computed observable, and observables accessed by one binding won't affect any others. To receive all the benefits of independent bindings, you should note the following interface changes: (The old interfaces are still supported for backwards compatibility.)

      • Within binding handlers, access sibling bindings by calling the get method of the allBindings parameter. To check for the existence of a sibling binding, use the has method. Getting the value of a sibling binding adds a dependency on any observables accessed in the binding's value expression.
      • ko.applyBindingsToNode is superseded by ko.applyBindingAccessorsToNode. The second parameter takes an object with pairs of bindings and value-accessors (functions that return the binding value). It can also take a function that returns such an object. (This interface isn't currently documented on the website.)
      • A binding provider should implement a getBindingAccessors function instead of (or in addition to) getBindings. Similarly to the above, it should return an object with bindings and value-accessors for any nodes that have bindings. (The binding provider interface also isn't documented on the website.)
    2. Ordered bindings: When an element has more than one binding, and when the order of updating those bindings is important, such as value: selectedValue, options: choices, Knockout will bind them in the right order. This is handled automatically for built-in bindings, and custom bindings can take advantage of this through a new interface. A binding handler can have an after property with an array of other bindings that it should come after. For example, the value handler has after: ['options', 'foreach'].

    3. Preprocessing bindings: Binding handlers can define a preprocess function that is called with the code of the binding value before it is evaluated. This can be used to modify the value or add extra bindings based on the value. Suppose you have a binding that expects a string, but you want to allow the user to provide an unquoted string. You could define a preprocess function that adds quotes to unquoted values:

      preprocess: function(value) {
          if (value[0] !== "'" && value[0] !== '"')
              return '"' + value + '"';
          else
              return value;
      }
      
    4. Preprocessing nodes: The binding provider can define a preprocessNode function that is called with each node in the document before it is processed for bindings. This function can modify the node or replace it with new nodes. This could be used to make syntax like Name: {{ firstName }} work by detecting {{ expr }} expressions in text nodes and inserting <!-- ko text: expr --><!-- /ko --> before binding are applied to that node.

    5. Dynamic binding handlers: Normally, binding handlers are defined before bindings are applied by adding handler objects to ko.bindingHandlers. But you can also define handlers dynamically by overriding the ko.getBindingHandler function. This function is given a binding string and returns the handler for that binding (or undefined if none exists). Here's an example that allows you use any binding starting with data- to set data attributes:

      var originalGetHandler = ko.getBindingHandler;
      ko.getBindingHandler = function(bindingKey) {
          var handler = originalGetHandler(bindingKey);
          if (!handler && bindingKey.match(/^data-/)) {
              handler = ko.bindingHandlers[bindingKey] = {
                  update: function(element, valueAccessor) {
                      element.setAttribute(bindingKey, ko.unwrap(valueAccessor()));
                  }
              };
          }
          return handler;
      }
      
    6. checkedValue binding: Normally, the checked binding will use the input's value property, which is limited to string values, when updating its value. But if you also provide a checkedValue binding, its value will be used instead; this provides a way to use a value of any type with the checked binding.

    7. Observable view models: This is still a bit experimental. The idea is that you can have the view model be dynamic without having to use templates and re-render the whole DOM. Instead, changing the view model will update each of the individual bindings. More detail later...

    8. options binding generates change event: When the options change, the options binding tries to maintain the list selection so that the value of the selection stays the same. But if the selection changes because the selected value was removed, the options binding will generate a change event for the element. Other bindings that listen for change events, such as value and selectedOptions, will then be updated.

    Source code(tar.gz)
    Source code(zip)
  • v2.3.0(Jul 8, 2013)

    Features:

    • hasfocus renamed to hasFocus (hasfocus will still continue to work as well)
    • name parameter of template can accept an observable
    • ko.unwrap added as substitute for ko.utils.unwrapObservable
    • options binding uses same technique as foreach to avoid unnecessary re-rendering
    • optionsAfterRender callback added to allow for custom processing of the added options
    • optionsCaption will display a blank caption if the value is an empty string

    Bugs fixed:

    • hasfocus: requires two Tab presses to blur (and related issues) in Chrome; throws error in IE9 on initial binding
    • Error when you try to inline knockout because of </script> string
    • If first node in string template has a binding, the bindings in the template won't get updated
    • selectedOptions doesn't update non-observable properties
    • css won't accept class names with special characters
    • Applying binding twice to the same nodes fails in strange ways (now it fails with an obvious error message)
    • Two-way bindings overwrite a read-only computed property with a plain value
    • Empty template throws an error with jQuery 1.8+
    • observableArray can be initialized with non-array values
    • Event binding init fails if Object.prototype is extended (fixed all for...in loops)
    • Calling ko.isSubscribable with null or undefined causes an error
    • Binding to null or undefined causes an error
    • Memory leak in IE 7, 8 and 9 from event handlers
    • options binding causes error in IE8+ in compatibility mode
    • value binding on select doesn't match null with caption option
    • Invalid element in string template can cause a binding error
    • Conditionally included select gets close to zero width in IE7-8
    • ko.toJS treats Number, String and Boolean instances as objects
    • value binding misses some updates (1 -> "+1")
    • Exception in ko.computed read function kills the computed
    • Error if spaces around = in data-bind attribute in string template

    Maintenance:

    • Port tests to Jasmine
    • Support Node.js
    • Remove build output files and Windows build scripts
    • Build script runs tests using build output (using PhantomJS and Node.js)
    • Use faster string trim function
    • Add automated multi-browser testing using Testling-CI
    Source code(tar.gz)
    Source code(zip)
    knockout-2.3.0.debug.js(178.91 KB)
    knockout-2.3.0.js(41.73 KB)
  • v2.2.0(Apr 8, 2017)

    Bindings enhancements

    • The css binding accepts multiple classes in a string and dynamic class names.
    • The text binding can be used in virtual elements: <!--ko text: myValue--><!--/ko-->
    • For the options binding, it will skip destroyed items (unless optionsIncludeDestroyed is passed as truthy), optionsValue can accept a function just like optionsText, and optionsCaption can be an observable.
    • The with binding will bind to the original child DOM elements when its initial value is truthy, and keep a copy of the elements as a template.
    • The if and ifnot bindings will bind to the original child DOM elements when the initial value is truthy for if or falsy for ifnot. Additionally, they will only re-render the content when the truthiness of the value changes.
    • The attr binding handles the name attribute properly in older versions of IE.

    Computed observable and binding dependency enhancements

    • Observables (including computed) include a peek function for access within a computed without adding a dependency.
    • observableArray mutation functions no longer cause a dependency within a computed.
    • Writes to writable computeds can now be chained like observables.
    • Computed observables now have an isActive function that indicates that the computed has dependencies (can be triggered again).
    • change (normal manual subscription) and beforeChange callbacks no longer create dependencies.

    foreach and template enhancements

    • When a function is used for the template name, it now receives the binding context as the second argument.
    • The foreach functionality now does its best to understand items that were moved and move their content rather than re-render them.
    • beforeMove and afterMove callbacks can now be configured when using foreach functionality.
    • The foreach and template bindings now accept an as option to give $data an alias.
    • The afterRender, beforeRemove, afterAdd, beforeMove, and afterMove callbacks will no longer cause dependencies.

    Other binding enhancements

    • The ko object is now available from within bindings, even if ko is not global, such as when used with an AMD loader.
    • Can access the current element in a binding using the $element variable.
    • Can access the current context directly in a binding using the $context variable.
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Apr 8, 2017)

CrossUI is a free Cross-Browser Javascript framework with cutting-edge functionality for rich web application

CrossUI is a free Cross-Browser Javascript framework with cutting-edge functionality for rich web application

Jack Li 1.4k Jan 3, 2023
A declarative, HTML-based language that makes building web apps fun

A declarative, HTML-based language that makes building web apps fun ?? Docs โˆ™ Try Online โˆ™ Contribute โˆ™ Get Support Intro Marko is HTML re-imagined as

Marko 12k Jan 3, 2023
Turbolinks makes navigating your web application faster

Turbolinks is no longer under active development Please note that Turbolinks is no longer under active development. It has been superseded by a new fr

Turbolinks 12.8k Jan 4, 2023
OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on almost any browser of your choice.

OpenUI5. Build Once. Run on any device. What is it? OpenUI5 lets you build enterprise-ready web applications, responsive to all devices, running on al

SAP 2.7k Dec 31, 2022
World's smallest responsive ๐Ÿ”ฅ css framework (395 bytes)

lit ?? a ridiculously small responsive css framework. I challenged myself to see how small I could go, but preserve everything Skeleton, Milligram, an

Arham Jain 1.9k Jan 7, 2023
The simplest way to create web components from plain objects and pure functions! ๐Ÿ’ฏ

?? One of the four nominated projects to the "Breakthrough of the year" category of Open Source Award in 2019 hybrids is a UI library for creating web

hybrids 2.7k Dec 27, 2022
Create blazing fast multithreaded Web Apps

Welcome to neo.mjs! neo.mjs enables you to create scalable & high performant Apps using more than just one CPU, without the need to take care of a wor

neo.mjs 2.4k Dec 31, 2022
๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

Supporting Vue.js Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of these awesome ba

vuejs 201.6k Jan 7, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

React ยท React is a JavaScript library for building user interfaces. Declarative: React makes it painless to create interactive UIs. Design simple view

Facebook 200k Jan 4, 2023
Ember.js - A JavaScript framework for creating ambitious web applications

Ember.js is a JavaScript framework that greatly reduces the time, effort and resources needed to build any web application. It is focused on making yo

Ember.js 22.4k Jan 4, 2023
๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

vue-next This is the repository for Vue 3.0. Quickstart Via CDN: <script src="https://unpkg.com/vue@next"></script> In-browser playground on Codepen S

vuejs 34.6k Jan 4, 2023
Relay is a JavaScript framework for building data-driven React applications.

Relay ยท Relay is a JavaScript framework for building data-driven React applications. Declarative: Never again communicate with your data store using a

Facebook 17.5k Jan 1, 2023
A rugged, minimal framework for composing JavaScript behavior in your markup.

Alpine.js Alpine.js offers you the reactive and declarative nature of big frameworks like Vue or React at a much lower cost. You get to keep your DOM,

Alpine.js 22.5k Jan 2, 2023
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Inferno is an insanely fast, React-like library for building high-performance user interfaces on both the client and server. Description The main obje

Inferno 15.6k Dec 31, 2022
Tiny (2 KB) turboboosted JavaScript library for creating user interfaces.

Develop web applications with 100% JavaScript and web standards. ?? RE:DOM is a tiny (2 KB) UI library by Juha Lindstedt and contributors, which adds

RE:DOM 3.2k Jan 3, 2023
A JavaScript Framework for Building Brilliant Applications

mithril.js What is Mithril? Installation Documentation Getting Help Contributing What is Mithril? A modern client-side JavaScript framework for buildi

null 13.5k Dec 28, 2022
A modest JavaScript framework for the HTML you already have

Stimulus A modest JavaScript framework for the HTML you already have Stimulus is a JavaScript framework with modest ambitions. It doesn't seek to take

Hotwire 11.7k Dec 29, 2022
A functional and reactive JavaScript framework for predictable code

Cycle.js A functional and reactive JavaScript framework for predictable code Website | Packages | Contribute | Chat | Support Welcome Question Answer

Cycle.js 10.2k Jan 4, 2023
A declarative, efficient, and flexible JavaScript library for building user interfaces.

Solid is a declarative JavaScript library for creating user interfaces. It does not use a Virtual DOM. Instead it opts to compile its templates down t

Ryan Carniato 24.5k Jan 4, 2023