Dataflow-oriented programming for JavaScript
npm install tillberg-tboneTBone  
=====
TBone brings the power and expressive ease of live HTML templates to
JavaScript code, giving you the ability to build complex applications
using declarative/idempotent code.
TBone concepts:
- tbone.models.base:
- Set data to it via .query(prop, value).
- Read and bind to data via .query(prop).
- Supports deep-lookups and deep-binding, e.g. .query('users.2.name.first').
- Supports Object, Array, Number, String, Date, null, and undefined.
- tbone.models.bound:
- Extends tbone.models.base.
- Instead of setting data via query, the data held is bound to the
return value of a state function.
- This state function can query values from other models as part of
its calculation; whenever those other models are update, the state
function is automatically re-run in order to recalculate.
- tbone.models.async:
- Extends tbone.models.bound.
- Similar to bound models, but the state function returns data via
an async callback.
- Handles update generations for you, preventing older, slower updates
from overwriting newer, faster updates.
- tbone.models.ajax:
- Extends tbone.models.async.
- A special case of async model where the state function calls
.url() to build a URL to GET. The url function can query other
models to build the URL, enabling ajax models to respond to state
transitions by fetching new data.
- tbone.autorun:
- Creates a FunctionRunner that wraps a function, executes it,
attaches bindings to all models queryed during execution, then
re-runs the function whenever any of those bindings fire.
- Execution is controlled by a central Scheduler that orders functions
by priority and executes all waiting FunctionRunners synchronously
after a 0ms-timeout. The short delay removes the need for using
_.defer to prevent multiple bindings from causing multiple update
calls to the same FunctionRunner.
``javascriptfullname
// Bind to be the concatenation of first and last
T('fullname', function () {
return T.text('first') + ' ' + T.text('last');
});
T('first', 'Sally'); // Set first to 'Sally'last
T('last', 'Smith'); // Set to 'Smith'
// Set last to 'Rogers' after 2 seconds
setTimeout(function () {
T('last', 'Rogers');
}, 2000);
// Create an auto-executing T-function that sets span text based on fullname`
T(function () {
$('span').text(T.text('fullname'));
// -> "Sally Smith"
// -> after 2 seconds, "Sally Rogers"
});
In addition to declarative-programming infrastructure, TBone provides
functions for rendering live templates/views, as well as models and
collections.
TBone was originally built as an extension upon Backbone.
* Production version, minified 5.6kb gzipped
`html`
* Underscore.js or Lodash.
* JQuery or Zepto (TBone uses either only for the provided ajax function).
Bugfix? Cool new feature? Alternate style? Send us a pull request!
Below are some instructions for developing with TBone:
1. Make sure Node.js is installed.
1. Clone TBone
`bash`
$ git clone git@github.com:appneta/tbone.git
$ cd tbone
1. We use gulp to develop, test, and compile TBone
into /dist:
`bash`
$ npm install -g gulp
$ npm install
$ gulp
1. Create a feature branch and make some code changes
1. Add unit tests (in /test) and ensure your tests pass by runninggulp
.
1. Send us a detailed pull request explaining your changes.
Run fn now, and again anytime its dependencies change.
- fn: Function. This is executed immediately. fn will get re-run
again anytime the T-references it makes change. Thus, generally fn
should be idempotent,
though advanced users may find other strategies useful.
Gets prop and bind current T-function to changes in it.
- prop: String. e.g. 'name' or 'person.name.first'
Sets prop to value.
- prop: String. e.g. 'name' or 'person.name.first'.
- value: any serializable object (String, Number, Array, Object, Date),
or a TBone/Backbone model/collection.
Binds prop to the live result of fn
- prop: String. e.g. 'name' or 'person.name.first'.
- fn: Function. The return value of this function will be set to prop.
This function gets re-run any time its dependencies change.
T (or tbone) is just a TBone model. You can make more!
- tbone.models.base: Base TBone Modeltbone.models.bound
- : The base class for models that are bound to source dataT(prop, fn)
via a function. This is used to implement .tbone.models.async
- : Asynchronous version of the bound model. Prevents callbackstbone.models.ajax
from setting data for out-of-date updates.
- : Binds to an ajax endpoint specified by the url functionmodel.extend(prototypeProperties)
you define. Only makes ajax requests when a View depends on this data either
directly or through a chain of bound models.
- : Creates your very own TBone Model prototype.model.make(instanceProperties)
- : Make a new model instance.
- model(...): Models are callable, using the Three (or Four) Tenets of TBone above.model.query(prop, [value])
- : Look up prop, and either return the current valuemodel.queryModel(prop)
or set it to value if specified.
- : Look up prop and return the the model found theremodel.toggle(prop)
instead of extracting its data.
- : sets prop to !prop, i.e. alternate betweenmodel.push(prop, value)
true and false.
- : Add value at the end of the list at prop.model.unshift(prop, value)
- : Insert value at beginning of the list atmodel.removeFirst(prop)
prop.
- : Remove the first item from the list at prop,shift
like except that you don't get the value back.model.removeLast(prop)
- : Remove the last item from the list at prop,pop
like except that you don't get the value back.model.unset(prop)
- : Delete the specified property. Practically equivalentmodel.query(prop, undefined)
to using .model.increment(prop, number)
- : Adds number to prop. Use a negative
number to subtract.
- model.url: Override this to set either a URL or function that returnsmodel.state
a URL to fetch data via XHR. If a function, you can use T-references to
make this model re-fetch data on a property change (e.g. applying a filter).
- : Override this with a function to generate this model's data.T(prop, fn)
This has similar utility to .
TBone Collections are a subclass of Model. The main difference is that the
root data item is an Array instead of an Object. Define model in a
subclass to automatically create models of that type via add.
- tbone.collections.base: Base TBone Collection.collection.extend
- , collection.make, etc.: Same as for Models.collection.add(modelOrData)
- : Add a model to the collection. If raw datacollection.remove(modelOrId)
is passed instead, a model (of type specified by the model property of
the collection) is created automatically.
- : Remove a model from the collection.
To query for a model in a collection, use the pound sign (#) followed by the
ID of the model. For example, T('users.#42.name').
- TBONE_DEBUG: Set to true just before loading TBone in order to enabletbone.freeze()
debug output & features (not available using Production minified source).
- : Freeze the page; no further TBone updates will occur.tbone.watchLog(query)
- : Output log information to the console for query.tbone.noConflict()
Interesting things to try: 'scheduler', 'exec', 'lookups', or the name of
View/Model/Collection.
- : Reset T and tbone to what they were before TBonetbone.isReady()
loaded.
- : There are no pending Model/View updates, including ajaxtbone.getListeners(model)
models that are waiting for XHRs to finish. This is helpful for automated
testing to determine that the page has "settled".
- : Returns list of all the unique listenerstbone.hasViewListener(model)`: Returns true if a View is listening
that [recursively!] depend on model.
-
either directly or indirectly (i.e. through other model dependencies) for
changes to model. This is used internally by TBone to prevent loading
ajax data for any models that are not needed as part of the UI currently.
Copyright (c) 2012-2015 Dan Tillberg, AppNeta
TBone is freely redistributable under the MIT License. See LICENSE for details.