Code coverage report for lib/Context.js

Statements: 100% (33 / 33)      Branches: 100% (4 / 4)      Functions: 100% (7 / 7)      Lines: 100% (33 / 33)      Ignored: none     

All files » lib/ » Context.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143          1   1                 1   20               17               17   17   17               17                       1 10                 1 7                 1 9 9                     1   10 1     9   8   8 4     8                     1 2 2                     2 3 1 1       1       1    
/**
 * @file context
 * @author Leon(leon@outlook.com)
 */
 
var u = require('underscore');
 
var invariant = require('./util/invariant');
 
/**
 * `ei`视图上下文
 *
 * @constructor
 * @param {*} initialValue 初始化状态
 * @param {!Function} reducer 裁剪器
 */
function Context(initialValue, reducer) {
 
    invariant(u.isFunction(reducer), 'Context need a reducer');
 
    /**
     * 剪裁器
     *
     * @private
     * @member {Function}
     */
    this.reducer = reducer;
 
    /**
     * 数据仓库
     *
     * @private
     * @member {*}
     */
    this.store = initialValue;
 
    this.dispatch = u.bind(this.dispatch, this);
 
    this.getState = u.bind(this.getState, this);
 
    /**
     * 数据变化侦听函数
     *
     * @private
     * @member {Array.<Function>}
     */
    this.listeners = [];
 
}
 
/**
 * 对当前的数据进行剪裁
 *
 * @public
 * @param  {*}       state 数据状态
 * @param  {!Object} action 动作
 * @return {*} 新的数据状态
 */
Context.prototype.reduce = function (state, action) {
    return this.reducer(state, action);
};
 
/**
 * 获取当前上下文中的数据
 *
 * @public
 * @return {*}
 */
Context.prototype.getState = function () {
    return this.store;
};
 
/**
 * 设置当前的数据状态
 *
 * @param {*} store 数据状态
 * @return {module:Context}
 */
Context.prototype.setState = function (store) {
    this.store = store;
    return this;
};
 
 
/**
 * 派发动作,激活数据剪裁
 *
 * @public
 * @param {!Object} action 动作
 * @return {Object} 动作
 */
Context.prototype.dispatch = function (action) {
 
    if (u.isFunction(action)) {
        return action(this.dispatch, this.getState);
    }
 
    var nextState = this.reduce(this.store, action);
 
    this.setState(nextState);
 
    for (var listeners = this.listeners.slice(), i = 0, len = listeners.length; i < len; ++i) {
        listeners[i]();
    }
 
    return action;
 
};
 
/**
 * 添加数据变化侦听器
 *
 * @public
 * @param {!Function} handler 处理函数
 * @return {module:Context}
 */
Context.prototype.addChangeListener = function (handler) {
    this.listeners.push(handler);
    return this;
},
 
/**
 * 移除数据变化侦听器
 *
 * @param {!Function} handler 处理函数
 * @return {module:Context}
 */
Context.prototype.removeChangeListener = function (handler) {
 
    for (var listeners = this.listeners, i = listeners.length - 1; i >= 0; --i) {
        if (listeners[i] === handler) {
            listeners.splice(i, 1);
            return this;
        }
    }
 
    return this;
 
};
 
module.exports = Context;