jQuery插件结构。带有选项的方法,方法和选项

4
我一直在尝试理解如何构建一个良好的插件结构,以便它可以接受带选项的方法调用、纯方法调用、带选项的初始化以及不带选项的初始化。
到目前为止,这是我所拥有的内容。
(function($) {
    var settings = {};
    var defaults = {
        args : "default args"
    };
    var methods = {
        init : function(options) {
            if(options) {
                settings = $.extend({},defaults,options);
            }
        },
        test : function(arg) {
            alert("test: " + arg.args);
            alert("args: " + settings.args);
        }
    };
    $.fn.dataTable = function(method) {
        var args = arguments;
        var $this = this;
        return this.each(function() {
            if ( methods[method] ) {
                return methods[method].apply( $this, Array.prototype.slice.call( args, 1 ));
            } else if ( typeof method === 'object' || ! method ) {
                return methods.init.apply( $this, args );
            } else {
                $.error( 'Method ' +  method + ' does not exist on jQuery.plugin' );
            }  
        });
    };

})(jQuery);


$(document).ready(function(){
    $(".tbl").dataTable();
    //$(".tbl").dataTable({ args : "hello world" });
    $(".tbl").dataTable("test",{args:"test args passed"});
    //$(".tbl").dataTable("test");
});

然而,我收到以下内容:

测试:传递的测试参数

参数:未定义

需要帮助吗?

1个回答

3
(function($) {
    var defaults = {
        string1 : "hello ",
        string2 : "world!"
    };
    var methods = {
        init : function(options) {
            if(options) {
                $.extend(defaults,options);
            }
            alert(defaults.string1 + defaults.string2);
        },
        test : function(arg) {
            alert("test: " + arg.args);
            alert("args: " + defaults.string1 + defaults.string2);
        }
    };
    $.fn.dataTable = function(method) {
        var args = arguments;
        var $this = this;
        return this.each(function() {
            if ( methods[method] ) {
                return methods[method].apply( $this, Array.prototype.slice.call( args, 1 ));
            } else if ( typeof method === 'object' || ! method ) {
                return methods.init.apply( $this, Array.prototype.slice.call( args, 0 ) );
            } else {
                $.error( 'Method ' +  method + ' does not exist on jQuery.plugin' );
            }  
        });
    };

})(jQuery);


$(document).ready(function(){
    $(".tbl").dataTable();
    //$(".tbl").dataTable({ string1 : "foo", string2 : "bar" });
    $(".tbl").dataTable("test",{args:"test args passed"});
    //$(".tbl").dataTable("test");
});

1
我唯一的担忧是,如果我尝试在一个页面上初始化两个插件实例,这可能会产生复杂性。var $this = this - rlemon
1
我知道这是一个老帖子,但还是谢谢!另外,关于你的评论,不要使用.apply($this...),而是使用.apply($(this)...),至少可以使用.each()函数中的单个元素。 - Scrimothy
是的,这一行必须写成:return methods[method].apply($(this), Array.prototype.slice.call(outerArguments, 1));以便在每个循环中应用函数到一个特定的元素,否则例如当$this是8个匹配div的数组时,将导致调用函数64次(8个循环x每个循环8个元素)。默认的init部分也是如此。这意味着$this赋值不是必需的,可以被删除。我将其命名为outerArguments而不是args,以使代码更清晰,但这对于$(this)问题并不重要。 - Xavi Montero
@rlemon:使用$(this)而不是$this,我正在初始化8个独立的实例,并且运行良好。 - Xavi Montero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接