backbone@next implemented with plain old javascript with minimal dependencies
Callback is the event system in pojs. it is used for module-to-module or module-to-collection communication
Callback.on(event, callback, [context])
Bind a callback function to an object. The callback will be invoked whenever the event is fired. If you have a large number of different events on a page, the convention is to use colons to namespace them: "poll:start", or "change:selection".
Callback.off([event], [callback], [context])
Remove a previously-bound callback function from an object. If no context is specified, all of the versions of the callback with different contexts will be removed. If no callback is specified, all callbacks for the event will be removed. If no event is specified, callbacks for all events will be removed.
Callback.trigger(event, [*args])
Trigger callbacks for the given event. Subsequent arguments to trigger will be passed along to the event callbacks.
purpose of collection
- cache data on client side
- network communication
- communication channel between modules
new Collection([seed], [name], [options])
Collections are ordered sets of models.
inital data to populate collection
prefix of localstorage key, if absent collection wont be saved to localstorage
define options.idAttr to override the default id index key
define options.ajax to override the default ajax network request function use by collection
define options.cache to override the default localstorage cache function
Collection constructor only process the first one arguments (seed), addtional arguments are processed by Collection.init function.
the default init function
init:function(name, opt){
this.name = name
opt = opt || {}
this.ajax = opt.ajax || this.ajax
this.idAttr = opt.idAttr || this.idAttr
}collection only cache the data if name is a valid string
Collection.init can be overriden by extend function or inherit keyword
// in customcollection.js
const Collection = require('po/collection')
Collection.extend({
init:function(jwt){
this.name = 'CustomColl'
this.idAttr = '_key'
this.ajax = function(method,route,params,cb){
if (!route) return cb(null,params)
pico.ajax(method,route,params,{Authorization: 'Bearer' + jwt},function(err,state,res){
if (4!==state) return
if (err) return cb(err)
try{var obj=JSON.parse(res)}
catch(ex){return cb(ex)}
cb(null,obj)
})
}
return true
}
})
// in another.js
const CustomCollection = require('customcollection')
const coll = new CustomCollection(null, {}, jwt); // name, opt arguments are no longer needed in CustomerCollectionif the default ajax function doesn't meet your requirement, for example you need addtional headers. you can override it by passing in a new ajax function
// pico is already defined
function aclosure(jwt){
const options = {
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + jwt
}
}
return {
ajax(method, route, params, cb){
if (!route) return cb(null,params)
pico.ajax(method,route,params,options,function(err,state,res){
if (4!==state) return
if (err) return cb(err)
try{var obj=JSON.parse(res)}
catch(ex){return cb(ex)}
cb(null,obj)
})
}
}
}
const coll = new Collection(null, {}, 'example', aclosure(jwt));Collection has Callback built in.
These are the events supported
- add: when new model added to collection
- update: when an existing model got updated
- delete: when an existing model got deleted
- clear: when the collection got cleared
Example
// in amodule.js
// newModel will be trigger 2 times
function newModel(coll, id){
// this === amodule instance
}
return {
start(opt, coll){
coll.on('add', newModel, this)
coll.create({id: 1, value: 'a'})
coll.create({id: 2, value: 'b'})
}
}collection.add(models, cb)
Add an array of raw object to the collection, firing an "add" event for each object added to collection as model
const coll = new Colection()
coll.create({id: 1, value: 'a'})collection.list([filter1], [filter2], cb)
Get all models from a collection. only read from local storage if no filter1 and filter2 passed in
you can specified startId and lastId as filter1 and filter2, list will return an array models which id in (startId, lastId). list will trigger network call to upstream to get missing models in local storage
collection.list(1, 100, () => {})you can also specified array of need id as filter1, list will return an array models which id in filter1. list will trigger network call to upstream to get missing models in local storage
collection.list(['dog', 'cat'], () => {})There are two ways to extend a module
- use the
extendbuilt in method - use
inheritkeyword, it is synxtax sugar ofrequire+extendinheritis more convenient but.extendis more flexible it allow you to extend multiple objects in a file
Example:
// CustomModule.js
const Module = require('po/module');
return Module.extend({
start(opt, param1){
Module.prototype.start.call(this, opt);
// extra processing here
}
});
// othermodule.js
const CustomModule = inherit('CustomModule')
return {
start(opt, param1){
CustomModule.prototype.start.call(this, opt, param1);
}
}Module has Callback builtin to support event communication between modules
Example
// module1.js
function onHello(data){
console.log(data) // 'abc'
}
function onWorld(data){
console.log(data) // 'def'
}
return {
start(opt, mod2){
this.peer = mod2
mod2.callback.on('hello', onHello, this)
this.callback.on('world', onWorld, this)
},
go(){
this.peer.callback.trigger('foo', 123)
this.callback.trigger('bar', 456)
}
}
// module2.js
function onFoo(data){
console.log(data) // 123
}
function onBar(data){
console.log(data) // 456
}
return {
start(opt, mod1){
this.peer = mod1
mod1.callback.on('bar', onBar, this)
this.callback.on('foo', onFoo, this)
},
go(){
this.peer.callback.trigger('world', 'def')
this.callback.trigger('hello', 'abc')
}
}
// in parent of module1 and module2
const m1 = new Module1
const m2 = new Module2
m1.start(null, m2)
m2.start(null, m1)
m1.go()
m2.go()load test/test.html in browser, result is in console panel