reactive
Reactive template engine for robust real-time rendering of model data changes.
Installation
With component:
$ component install component/reactive
With the stand-alone browser build:
<script src="reactive.js"></script>
API
reactive(element, object, [view])
Bind object
to the given element
with optional view
object. When a view
object is present it will be checked first for overrides, which otherwise delegate to the model object
.
For example if you have the following HTML:
And pass the following object
as the second argument:
name: 'Tobi'
The output will become:
Tobi
However if you wish to manipulate the output or provided computed properties thae view
object may be passed. For example an object
of:
first_name: "Tobi" last_name: "Ferret"
And a view
of:
{ thisuser = user;} UserViewprototype{ return thisuserfirst_name + ' ' + thisuserlast_name;}
Would produce:
Tobi Ferret
Typically a view object wraps a model to provide additional functionality, this may look something like the following:
{ thisuser = user; thisel = ;} UserViewprototype{ ... }
Often a higher-level API is built on top of this pattern to keep things DRY but this is left to your application / other libraries.
Adapters
Subscriptions
Subscriptions allow reactive to know when an object's data has changed updating the DOM appropriately without re-rendering a static template. This means if you make manual DOM adjustments, append canvases etc they will remain intact.
By default reactive subscribes using .on("change <name>", callback)
however it's easy to define your own subscription methods:
reactive; reactive;
Getting and Setting
You can make reactive compatible with your favorite framework by defining how reactive gets and sets the model.
By default reactive supports obj[prop] = val
and obj[prop](val)
, but these can be changed with reactive.get(fn)
and reactive.set(fn)
. Here's how to make reactive compatible with backbone:
reactive; reactive;
Interpolation
Bindings may be applied via interoplation on attributes or text. For example here
is a simple use of this feature to react to changes of an article's .name
property:
{name}
Text interpolation may appear anywhere within the copy, and may contain complex JavaScript expressions for defaulting values or other operations.
{ name || 'Untitled' } Summary: { body.slice(0, 10) }
Reactive is smart enough to pick out multiple properties that may be used, and react to any of their changes:
Welcome { first + ' ' + last }.
Interpolation works for attributes as well, reacting to changes as you'd expect:
{filename} Download {filename}
Declarative Bindings
By default reactive supplies bindings for setting properties, listening to events, toggling visibility, appending and replacing elements. Most of these start with "data-*" however this is not required.
data-text
The data-text
binding sets the text content of an element.
data-html
The data-html
binding sets the inner html of an element.
data-<attr>
The data-<attr>
bindings allows you to set an attribute:
Download
on-<event>
The on-<event>
bindings allow you to listen on an event:
x
data-append
The data-append
binding allows you to append an existing element:
data-replace
The data-replace
binding allows you to replace an existing element:
data-{show,hide}
The data-show
and data-hide
bindings conditionally add "show" or "hide" classnames so that you may style an element as hidden or visible.
data-checked
Toggles checkbox state:
Writing bindings
To author bindings simply call the reactive.bind(name, fn)
method, passing the binding name and a callback which is invoked with the element itself and the value. For example here is a binding which removes an element when truthy:
reactive;
Computed properties
Reactive supports computed properties denoted with the <
character. Here the fullname
property does not exist on the model, it is a combination of both .first
and .last
, however you must tell Reactive about the real properties in order for it to react appropriately:
NOTE: in the future Reactive may support hinting of computed properties from outside Reactive itself, as your ORM-ish library may already have this information.
Interpolation
Some bindings such as data-text
and data-<attr>
support interpolation. These properties are automatically added to the subscription, and react to changes:
Notes
Get creative! There's a lot of application-specific logic that can be converted to declarative Reactive bindings. For example here's a naive "auto-submit" form binding:
var reactive = ; // bind var view = ; // custom binding available to this view only view;
For more examples view the ./examples directory.
License
MIT