The v2 branch of MDV is available here:
https://github.com/toolkitchen/mdv/tree/v2
I'm sure there are bugs lurking, but all (but the view-controller)
tests are working and I think it's worth playing with and reporting
bugs.
There are a number of big changes in this design:
-The .model property on Element & Node is gone.
Data is no longer *directly* bound to the DOM or dynamically
cascade-able (this is the biggest change).
Data is propagated by the act of the <template> element creating instances.
-Text.prototype.addBinding & Element.prototype.addBinding are now gone.
Node.prototype.bind()/unbind()/unbindAll() have replaced them. The
equivalents are:
myText.bind('textContent', obj, path)
myElement.bind(attrName, obj, path)
myInput.bind('value', obj, path)
myInput.bind('checked', obj, path)
Note that the above bind() method does not know how to parse mustache
strings - this a now a concern of <template> instance production (but
is available via HTMLTemplateElement.bindAll -- more below).
It is now up to the node itself to decide what to do with the binding
directive. Custom elements can now override bind/unbind/unbindAll() to
setup two-way bindings.
-<template> "iterate", "instantiate" are now gone. They are replaced
with "repeat", "bind" and "if" (as described in the earlier doc I sent
out).
The syntax is now also that data is only *ever* passed via mustaches.
So those familiar with the old
<template repeat="foo">
should now try
<template repeat="{{ foo }}">
also note that "naked" directives do not currently work, e.g.
<template repeat>.
Instead, you need
<template repeat="{{}}">
-In order to initially bind data to a template, use
HTMLTemplateElement.bindAll(node, model, opt_delegate).
We probably need different API for this (and especially for
registering delegates), but this is what we have for now.
Note that this will traverse the subtree from node and setup all
bindings found in mustaches (this is what <template> uses internally
to setup bindings on instances). If you just want to provide
data/delegate to a template, just specify the template node directly.
If you want to setup mustaches inside a shadowroot, *and* set the
<templates> in motion, use the the shadowroot as the provided node.
-The delegate API is now simpler.
The delegate is still a function, which is called with the contents of
*all* mustaches. e.g.
delegate(mustacheContentString, defaultModel)
The delegate has two valid choices:
1) Return undefined, meaning that it doesn't wish to override the
default behavior.
2) Return an obj, which is expected to have a 'value' property
(2) is entirely general purpose, it allows the delegate to create a
"synthetic" observed value which, itself, can observe whatever it
wishes.
To help with this, template_element.js now exports a global object
called CompoundBinding, which makes it easy to compose a synthetic
value which is composed of other observed values. e.g.
var compound = new CompoundBinding(function(values) {
// values is an object, name => value.
// will be called when one or more dependent values have changed.
return newComputedValue;
});
compound.bind('myThing', model, path);
compound.bind('otherThing', randomObject, path);
I fixed the existing delegates.js to use this new API. Everything
currently works, except the toSource() direction of transforms.
-----
I've got a more complete explainer in the works, but feel free to try
it out and send me bugs/issues/complaints.
R