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()