Hey folks
I'd like to start a conversation about some ideas for version 1.3.
There are a few big features I've been wanting to include for a while,
and the time seems right to put them in here. If you have other ideas
about what new functionality would benefit the majority of KO users
(without changing the entire scope of the project - e.g., there is not
going to be any server-side code!) please say so.
What I have in mind is:
Control flow bindings
===============
By giving bindings the ability to control binding of descendant nodes,
it becomes possible to add bindings like "if", "with", and "foreach"
that modify the DOM in a lightweight, convenient way without making
you use so many templates all the time.
* "if" would include/exclude descendant nodes, and means you don't
have to write "text: someChild() ? someChild().childProperty : null"
in case someChild() would be null, as you could wrap a section of the
DOM with "if: someChild".
* "with" would do the same as "if", plus it would change the binding
context to the supplied value. This lets you bind a section of
elements against a specific object, meaning that you can reference
their properties directly (e.g., "text: childProperty") instead of
forcing you to use fully-qualified references (e.g., "text:
someChild().childProperty").
* "foreach" would do the same as "with", except it operates on an
array and adds/removes descendants as items are added/removed in the
array.
Try these running prototypes right away :) :
* if:
http://jsfiddle.net/cJzzc/
* with:
http://jsfiddle.net/jm9W8/
* foreach:
http://jsfiddle.net/p7sUB/
These bindings don't replace templates entirely; they just give you a
lightweight, convenient alternative in many simple cases.
Inline templates
===========
The much-requested feature! Lets you replace this:
<div data-bind="template: { name: 'myTemplate', data: someObject }"></
div>
<script id="myTemplate" type="text/html">
Template markup goes here
</script>
... with this:
<div data-bind="template: someObject" style="display:none">
Template markup goes here
</div>
Extenders
=======
Often, people want to modify the behavior of an observable. For
example, you might want to ensure it only holds a numeric value. One
way you can already do it is by creating a function that returns a
writable dependent observable with your intended behavior, but this
isn't obvious and it's hard to combine multiple behaviors.
The idea of extenders is a bit like binding handlers - you can
register a set of extension functions that can be called when
initialising an observable or dependentObservable. For example, you'll
be able to initialise an observable like this:
var viewModel = {
myValue : ko.observable(0).extend({ numeric: true })
};
... as long as there is also a handler for "numeric", e.g.:
ko.extenders.numeric = function(target) {
return ko.dependentObservable({
read: target,
write: function(value) {
if (!isNaN(value)) { target(value) }
}
});
}
So, you can define your own library of extenders (or ask for help from
the community in creating one), and then easily merge the behaviors
into your view model. The other nice thing about this is that you can
compose behaviors together, for example you could define a "throttle"
extender that makes an observable that cannot notify faster than a
certain rate (e.g., once per second), and then combine the two
behaviors:
myValue : ko.observable(0).extend({ numeric: true, throttle:
2000 }) // Is numeric and updates no faster than once every 2 seconds
(2000 milliseconds)
History integration (may be a plugin)
==========================
I think there's huge potential for linking observables with URL
components, somewhat like Alisson has been showing here:
http://groups.google.com/group/knockoutjs/browse_thread/thread/75dbfeee65988569
I'd love to see a standard KO plugin for doing that linking. I don't
think it needs to tackle all the "single-page interface" details like
loading external templates, but if it just handled the core
observable<-->URL link, you can layer any form of navigation or
template management on top of that.
============
So, let me know what you think. The roadmap presently is:
* Implement and release 1.2.1, which should fix most of the
outstanding issues at
https://github.com/SteveSanderson/knockout/issues
* In parallel develop 1.3.0 (on this branch:
https://github.com/SteveSanderson/knockout/tree/1.3) and release later
when done.