Smack
A small Javascript library for events, observable objects, and data binding.
Installation
Smack can be used on the server with NodeJS or on the client, built with Browserify, so install with npm:
npm install smack
Usage
Eventable
, ChangeNotifier
, and Observable
can be either used directly as
class constructors (e.g, new Eventable()
), or as mixins with something like
typedef.mixin.
Eventable
mixin Run-of-the-mill events mixin. Similar to the Backbone Events API.
var Eventable = Eventable; var thing = ; thing; thing;// Hello! var another = ;another; thing;// Hey!// thing is shouting!
ChangeNotifier
mixin Mixin that uses events to signal to other objects that a change has occured. It serves as a standardized interface for handling object change and property change notifications.
The example below uses a mixin
funciton that simply adds the methods on the
prototype
property of one object to another.
var ChangeNotifier = ChangeNotifier;var mixin_ = mixin; ; { thishp = 100; thisstatus = 'alive';} Heroprototype thishp = Math; if thishp > 0 return; thisstatus = 'dead'; this; ... var guy = ; guy;
Observable
mixin An object that has all the methods of Eventable
and ChangeNotifier
mixed
in, with some helpful methods to automatically wire up certain properties to
fire change events.
var Observable = require('smack').Observable;
var Eventable = require('smack').Eventable;
var mixin_ = require('typedef').mixin;
mixin_(Person, Observable);
function Person()
{
}
Person.observable({
name: 'John',
age: 27
});
...
var bob = new Person();
bob.onPropertyChange({
name: function() { console.log('name changed!'); }
});
bob.name = 'Bob'
// name changed!
bob.name = 'Bob';
// [nothing]
bob.name = 'Bobby';
// name changPerson name changeded!
Binding
class A proxying object that allows you to connect a source to one or more targets.
This allows for a way to keep certain objects in sync via databinding. Assuming
a source implements/mixes in ChangeNotifier
, all targets will be kept in
sync.
// Using the Person class above ...var me = ; // Create a binding sourcing the 'name' property of the instance 'me'.var binding = ;binding; var nameTag = value: '[BLANK]' ; // Proxy all changes from the source (me#name) to the nameTag objectbinding; nameTagvalue // === '[BLANK]'mename = 'Brandon';nameTagvalue // === 'Brandon'
Bindings are extremely useful when creating de-coupled surfaces that you want data to remain in-sync across, without having to manually do the accounting.
Tern Support
The library files are all decorated with JSDoc3-style
annotations that work great with the Tern code inference
system. Combined with the Node plugin (see this project's .tern-project
file), you can have intelligent autocomplete for methods in this library.
Testing
Testing is done with Tape and can be run
with the command npm test
.
Automated CI cross-browser testing is provided by Testling.
License
Copyright 2014 Brandon Valosek
Smack is released under the MIT license.