Calcium is another Javascript/MVC bicycle. It heavily inspired by Backbone.js but, in contrast, has the following objectives:
- Avoid overbloated "god" objects.
- Minimal memory usage. Using RISK-like architecture.
- Completely predictable behavior.
- Browser-first. Support for node.js only if it does not interfere.
All Calcium located inside Ca
namespace.
Calcium provides very "standart" event mechanizm with some improvements. All
of them aimed at fighting "zombies". Events
module can be mixed in to any
object, giving the object the ability to bind and trigger custom named events.
var myEvented = _.extend(myObject, Ca.Events)
on(events, callback, [context], [doRelease])
By default on
takes two arguments: event and callback. Event is just
string event name. Callback is function.
To supply a context value for this
when the callback is invoked, pass the
optional third argument.
doRelease
flag makes sense only if context
is "evented" too. If so, on
automatically binds "forget" action on context
's "release" event.
off([events], [callback], [context])
emit(events, [args])
release([action])
Our brave zombie killer. Without any arguments, release
fires "release"
event, then it do cleanup actions in FIFO order. To define cleanup action,
provide function as argument.
Calcium model is different from Backbone's Model. Instead implement "fat" structure of models and collections, Calcium uses spine.js-like behaviour. But implementation of Model in Calcium is more lightweight.
Model holds records. Every record is tiny object with unique id.
Model emits events. Each event provides model and data
as arguments.
error
event emitted on problems. data
is hash with two fields: error
kind (validation for example) and info.
Creation of Model is pretty straightforward. You can extend base Model and provide overrides for instance.
var MyModel = Ca.Model.extend({ ... });
var model = new MyModel({ ... });
Also you can provide init
function. It will be invoked when model is
created.
var MyModel = Ca.Model.extend({
init : function(options) {
...
}
});
init
takes same arguments as constructor.
A records's ID is stored under record id
attribute. If you're directly
communicating with a backend (CouchDB, MongoDB) that uses a different unique
key, you may set a Model's id
to transparently map from that key to id.
var CouchModel = Ca.Model.extend({
id : '_id'
});
By default, Model.id is 'id'
.
To validate record on creation or changing, provide validate
function.
var StrictModel = Ca.Model.extend({
validate : function(attributes) {
if (!attributes.neededAttr)
return "neededAttr is required";
}
});
If validate
returns anything, the validation will fail and an 'error' event
will be fired on the on record. Also, 'error' event will be fired on model.
Validation error data is hash.
{
kind : 'validate',
info : [{
data : {...}, // Invalid data
reason : '...' // validate
result
}]
}
Calcium uses validate
in put
method of model and update
method of record.
All records available by Model's records
attribute. Its regular array where
records are in the order they were added. To get single record or set of
records use get
method.
var oneRecord = model.get(170);
var manyRecords = model.get([1,2,3]);
get
takes record ID or array of IDs and returns record or array according to
argument type. If records not found, get
will return undefined
or empty
array.
put(hashes, options);
To create or update records use put
method. It takes array of hashes and
optional options.
model.put([
{ f : '1', id: 1 },
{ f : '2', id: 2 }
]);
All hashes are validated before put in model. If any of hashes are invalid,
put
will fire "error" after all operations.
If hash hasn't ID attribute, Calcium automatically generate unique ID for record. Existent records with same IDs will be updated.
put
may emit two events: "update" and "add". "update" always fired first.
Model emit each event only after commiting. Both is optional.
"update" event data holds array of changes records. Each is hash with new and old record.
[ {record: ..., old: ...}, ... ]
"add" event data holds array of new records in order of addition.
[record, ...]
To supress events pass silent:true
to options.
model.put([ ... ], {silent:true});
To remove records which are not present in hashes, use reset:true
in options.
model.put([ ... ], {reset:true});
If hashes is completelly new, put
will fire
Events
reset
destroy
set
error
Mock
// props
id : 'id'
validate(hash)
parse(data)
serialize()
// methods
get(id || [id])
put([hash], {reset, silent})
destroy([id], {offline, silent})
store({silent})
fetch({reset, data})
Instance
id
model
get(attribute)
set(hash)
destroy()
store()