jQuery插件模式与数据持久性

时间:2011-08-22 16:03:50

标签: javascript jquery jquery-plugins plugin-pattern

我正在开发一个jQuery插件,但是我遇到了一些设计模式的问题,它结合了jQuery best practices的默认和选项,数据和命名空间技术。这是我的代码的抽象版本:

(function($) {
var defaults = {
    key1: 'value1',
    key2: 'value2'
};
var settings = {};
var methods = {
    init: function() {
        return this.each(function() {
            var $this = $(this), data = $this.data('pluginname');
            console.log('init called');
            // If the plugin hasn't been initialized yet
            if (!data) {
                //Do more setup stuff here
                $this.data('pluginname', {
                    key3: 'value3',
                    key4: 'value4'
                });
            }
            //test for settings and data
            console.log(settings);
            console.log(data);
        });
    },
    methodname: function() {
        return this.each(function() {
            var $this = $(this), data = $this.data('pluginname');
            console.log('methodname called');
            //test for settings and data
            console.log(settings);
            console.log(data);
        });
    }
};
$.fn.pluginname = function(method, options) {
    settings = $.extend({}, defaults, options);
    if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || ! method) {
        return methods.init.apply(this, arguments);
    } else {
        $.error( 'Method ' +  method + ' does not exist on jQuery.pluginname' );
    }    
};
$(document).ready(function() {
    $('body').pluginname();
    $('body').pluginname('methodname', {key1: 'overriding default value for key 1'});
});
})(jQuery);

如果您使用最新版本的jQuery运行该代码,您会看到我同时调用initmethodname函数并记录settingsdata个对象每个。在methodname调用中,我可以访问settingsdata,但在init调用本身中,data对象返回undefined。如果我在第21行的脚本中设置了断点,我可以在控制台中使用data回调$this.data('pluginname')对象。谁知道我在这里做错了什么?我应该能够在init,function中编写data.key3,对吧?

1 个答案:

答案 0 :(得分:2)

init方法中,在.each循环的最开始,您将存储在当前迭代元素中的对象分配给data变量。如果指定密钥没有可用数据,则data未定义。

然后测试data的真实性,如果评估为 false ,则继续将数据对象分配给当前元素。

稍后,您致电console.log(data);,它会为您提供undefined。这是预期的,因为data最初被分配undefined - 而这仍然是它所指的。修复:

// if undefined
if (!data) {
    //Do more setup stuff here


    $this.data('pluginname', {
        key3: 'value3',
        key4: 'value4'
    });
    data = $this.data('pluginname');
}