Ruby's Louvre

每天学习一点点算法

导航

mass Framework data模块 v4

对v3进行改进,原来是用两个引用数组为元素节点提供UUID,另外两个数组提供缓存体。v4中删掉Data类,只有一个数组来为元素节点提供UUID,再用一个数组提供缓存体。缓存体之上有一个data对象属性,用于保存用户数据。相对于v3与jQuery2.0的新方案,它会在没有私有数据与用户数据时,会把这两个数组对应位置上的元素删掉,防止无限膨胀。

//==================================================
// 数据缓存模块
//==================================================
define("data", ["$lang"], function($) {
    var owners = [],
        caches = [];
    /**
     * 为目标对象指定一个缓存体
     * @param {Any} owner
     * @return {Object} 缓存体
     * @api private
     */

    function add(owner) {
        var index = owners.push(owner);
        return caches[index - 1] = {
            data: {}
        };
    }
    /**
     * 为目标对象读写数据
     * @param {Any} owner
     * @param {Object|String} name ? 要处理的数据或数据包
     * @param {Any} data ? 要写入的数据
     * @param {Boolean} pvt ? 标识为内部数据
     * @return {Any}
     * @api private
     */

    function innerData(owner, name, data, pvt) { //IE678不能为文本节点注释节点添加数据
        var index = owners.indexOf(owner);
        var table = index === -1 ? add(owner) : caches[index];
        var getOne = typeof name === "string" //取得单个属性
        var cache = table;
        //私有数据都是直接放到table中,普通数据放到table.data中
        if(!pvt) {
            table = table.data;
        }
        if(name && typeof name == "object") {
            $.mix(table, name); //写入一组属性
        } else if(getOne && data !== void 0) {
            table[name] = data; //写入单个属性
        }
        if(getOne) {
            if(name in table) {
                return table[name];
            } else if(!pvt && owner && owner.nodeType == 1) {
                //对于用HTML5 data-*属性保存的数据, 如<input id="test" data-full-name="Planet Earth"/>
                //我们可以通过$("#test").data("full-name")或$("#test").data("fullName")访问到
                return $.parseData(owner, name, cache);
            }
        } else {
            return table;
        }
    }
    /**
     * 为目标对象移除数据
     * @param {Any} owner
     * @param {Any} name ? 要移除的数据
     * @param {Boolean} pvt ? 标识为内部数据
     * @return {Any}
     * @api private
     */

    function innerRemoveData(owner, name, pvt) {
        var index = owners.indexOf(owner);
        if(index > -1) {
            var delOne = typeof name == "string",
                table = caches[index],
                cache = table,
                clear = 1
            if(delOne) {
                if(!pvt) {
                    table = table.data;
                }
                if(table) {
                    delOne = table[name];
                    delete table[name];
                }
                for(var key in cache) {
                    if(key == "data") {
                        for(var i in cache.data) {
                            clear = 0;
                            break;
                        }
                    } else {
                        clear = 0;
                        break;
                    }
                }
                if(clear) {
                    owners.splice(index, 1);
                    caches.splice(index, 1);
                }
            }
            return delOne; //返回被移除的数据
        }
    }
    $.mix({
        //判定是否关联了数据
        hasData: function(owner) {
            return owners.indexOf(owner) > -1;
        },
        // 读写用户数据
        data: function(target, name, data) {
            return innerData(target, name, data);
        },
        //读写内部数据
        _data: function(target, name, data) {
            return innerData(target, name, data, true);
        },
        //移除用户数据
        removeData: function(target, name) {
            return innerRemoveData(target, name);
        },
        //移除内部数据
        _removeData: function(target, name) {
            return innerRemoveData(target, name, true);
        },
        //将HTML5 data-*的属性转换为更丰富有用的数据类型,并保存起来
        parseData: function(target, name, cache, value) {
            var data, key = $.String.camelize(name),
                _eval
            if(cache && (key in cache)) return cache[key];
            if(arguments.length != 4) {
                var attr = "data-" + name.replace(/([A-Z])/g, "-$1").toLowerCase();
                value = target.getAttribute(attr);
            }
            if(typeof value === "string") { //转换 /^(?:\{.*\}|null|false|true|NaN)$/
                if(/^(?:\{.*\}|\[.*\]|null|false|true|NaN)$/.test(value) || +value + "" === value) {
                    _eval = true;
                }
                try {
                    data = _eval ? eval("0," + value) : value;
                } catch(e) {
                    data = value;
                }
                if(cache) {
                    cache[key] = data;
                }
            }
            return data;

        },
        //合并数据
        mergeData: function(cur, src) {
            if($.hasData(cur)) {
                var oldData = $._data(src),
                    curData = $._data(cur),
                    events = oldData.events;
                $.Object.merge(curData, oldData);
                if(events) {
                    curData.events = [];
                    for(var i = 0, item; item = events[i++];) {
                        $.event.bind(cur, item);
                    }
                }
            }
        }
    });
    return $
});


posted on 2013-01-02 15:05  司徒正美  阅读(1213)  评论(0编辑  收藏  举报