tillberg-tbone
v3.0.0
Published
Dataflow-oriented programming for JavaScript
Downloads
30
Readme
TBone
Dataflow-Oriented Programming for JavaScript
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.
- Set data to it via
tbone.models.bound
:- Extends
tbone.models.base
. - Instead of setting data via
query
, the data held is bound to the return value of astate
function. - This
state
function can query values from other models as part of its calculation; whenever those other models are update, thestate
function is automatically re-run in order to recalculate.
- Extends
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.
- Extends
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. Theurl
function canquery
other models to build the URL, enabling ajax models to respond to state transitions by fetching new data.
- Extends
tbone.autorun
:- Creates a
FunctionRunner
that wraps a function, executes it, attaches bindings to all modelsquery
ed 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.
- Creates a
Example
// Bind `fullname` 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'
T('last', 'Smith'); // Set `last` 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.
Download
- Production version, minified 5.6kb gzipped
<script src="https://cdn.tbonejs.org/tbone-3.0.0.min.js"></script>
Requirements
- Underscore.js or Lodash.
- JQuery or Zepto (TBone uses either only for the provided
ajax
function).
Contribute
Bugfix? Cool new feature? Alternate style? Send us a pull request!
Below are some instructions for developing with TBone:
Make sure Node.js is installed.
Clone TBone
$ git clone [email protected]:appneta/tbone.git $ cd tbone
We use gulp to develop, test, and compile TBone into
/dist
:$ npm install -g gulp $ npm install $ gulp
Create a feature branch and make some code changes
Add unit tests (in
/test
) and ensure your tests pass by runninggulp
.Send us a detailed pull request explaining your changes.
The Three (or Four) Tenets of TBone
run: T(fn)
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.
get: T(prop)
Gets prop and bind current T-function to changes in it.
- prop: String. e.g. 'name' or 'person.name.first'
set value: T(prop, value)
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.
set function: T(prop, fn)
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.
TBone Models
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 data via a function. This is used to implementT(prop, fn)
.tbone.models.async
: Asynchronous version of the bound model. Prevents callbacks from setting data for out-of-date updates.tbone.models.ajax
: Binds to an ajax endpoint specified by the url function you define. Only makes ajax requests when a View depends on this data either directly or through a chain of bound models.model.extend(prototypeProperties)
: Creates your very own TBone Model prototype.model.make(instanceProperties)
: Make a new model instance.
Model methods
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 value or set it to value if specified.model.queryModel(prop)
: Look up prop and return the the model found there instead of extracting its data.model.toggle(prop)
: sets prop to !prop, i.e. alternate between true and false.model.push(prop, value)
: Add value at the end of the list at prop.model.unshift(prop, value)
: Insert value at beginning of the list at prop.model.removeFirst(prop)
: Remove the first item from the list at prop, likeshift
except that you don't get the value back.model.removeLast(prop)
: Remove the last item from the list at prop, likepop
except that you don't get the value back.model.unset(prop)
: Delete the specified property. Practically equivalent to usingmodel.query(prop, undefined)
.model.increment(prop, number)
: Adds number to prop. Use a negative number to subtract.
Model properties
model.url
: Override this to set either a URL or function that returns 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).model.state
: Override this with a function to generate this model's data. This has similar utility toT(prop, fn)
.
Collections
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 data is passed instead, a model (of type specified by the model property of the collection) is created automatically.collection.remove(modelOrId)
: 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')
.
Even more fun stuff!
TBONE_DEBUG
: Set to true just before loading TBone in order to enable debug output & features (not available using Production minified source).tbone.freeze()
: Freeze the page; no further TBone updates will occur.tbone.watchLog(query)
: Output log information to the console for query. Interesting things to try: 'scheduler', 'exec', 'lookups', or the name of View/Model/Collection.tbone.noConflict()
: ResetT
andtbone
to what they were before TBone loaded.tbone.isReady()
: There are no pending Model/View updates, including ajax models that are waiting for XHRs to finish. This is helpful for automated testing to determine that the page has "settled".tbone.getListeners(model)
: Returns list of all the unique listeners that [recursively!] depend on model.tbone.hasViewListener(model)
: Returns true if a View is listening 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.
License
Copyright (c) 2012-2015 Dan Tillberg, AppNeta
TBone is freely redistributable under the MIT License. See LICENSE for details.