Commit c18a196b by Иван Кубота

Store pipe feature. Functional way of piping values to simple processors. Covered by tests.

parent aa80b28f
......@@ -120,7 +120,17 @@ Store.prototype = {
this.parent = new StoreParent(parent, key, item);
},
bindings: function() {
var out = {};
var _self = this;
var out = {
_addOther: function(obj){
for(var key in obj)
if(_self.get(key) === void 0){
_self.set( key, obj[key] );
this[key] = _self.bind(key);
}
return this;
}
};
for(var k in this._props){
out[k] = this.bind(k);
}
......@@ -418,6 +428,59 @@ Store.prototype = {
bind: function (key) {
return Array.isArray(this._props[key]) ? this.array(key): new StoreBinding( this, key );
},
pipe: function(key){
var processors = [];
var subscribes = [];
var me = this;
var val, lastVal;
var un;
var dispatch = function(){
for( var i = 0; i < subscribes.length; i++ ) {
var subscribe = subscribes[ i ];
subscribe.apply(me, lastVal);
}
};
var process = function(){
var val;
for( var i = 0; i < processors.length; i++ ) {
var processor = processors[ i ];
if(i>0){
val = processor.fn.call( me, val );
}else {
val = processor.fn.apply( me, arguments );
}
if(processor.val === val)
return;
processor.val = val;
}
lastVal = [val];
dispatch();
};
var backwardCallback = function(update){
if(subscribes.length === 0){
un = me.sub(key, process);
}
subscribes.push(update);
update.apply(me, lastVal);
return function(){
for( var i = subscribes.length; i--; ) {
if(subscribes[ i ] === update){
subscribes.splice(i, 1);
}
}
if(subscribes.length === 0){
un();
}
};
};
backwardCallback.pipe = function(fn){
processors.push({process: true, fn, val: void 0});
return backwardCallback;
}
return backwardCallback;
},
val: function(key) {
const me = this;
return function backwardCallback(update) {
......@@ -614,6 +677,9 @@ Store.IF = function(cfg, children){
cfg.condition.hook( hook );
}else if(typeof cfg.condition === 'function'){
cfg.condition( hook );
}else if(typeof cfg.condition !== 'object'){
console.warn('Condition is not reactive');
update(!!cfg.condition);
}else{
// TODO other hooklikes
hook(cfg.condition)
......
......@@ -37,6 +37,43 @@ describe('store', function(){
assert.equal( s.get( 'a.b.d' ), void 0 );
} );
it( 'should pipe', function(){
const s = new Store( {} );
s.set( 'a', 5 );
var callID = 0;
var val = s.pipe( 'a')
.pipe(a=>Math.abs(a))
.pipe(a=>a*2)
.pipe(a=>a+2)
.pipe(a=>a+' cats ')
.pipe(a=>a.trim());
var result;
var un = val(_=>result = _ +':'+(callID++));
assert.equal( result, '12 cats:0' );
s.set('a', 6)
assert.equal( result, '14 cats:1' );
// No redundant calls if value does not change
s.set('a', -6)
assert.equal( result, '14 cats:1' );
// No redundant calls if value does not change
s.set('a', -5)
assert.equal( result, '12 cats:2' );
// garbage can be collected
un();
s.set('a', 10)
assert.equal( result, '12 cats:2' );
un = val(_=>result = _ +'|'+(callID++));
assert.equal( result, '22 cats|3' );
} );
it( 'should fire changes for simple values', function(){
const s = new Store( { a: 4, b: 5, c: 6 } );
let list;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment