即时创建方法

时间:2010-06-26 19:03:41

标签: javascript jquery plugins methods

您好我正在尝试创建一个jQuery插件,我需要在将元素初始化为该类对象后才能访问元素,例如:

$('.list').list({some options}); //This initializes .list as a list

//now I want it to have certain methods like:
$('.list').find('List item'); //does some logic that I need

我试过

$.fn.list = function (options) {
    return this.each(function() {
        // some code here
        this.find = function(test) {
            //function logic
        }
    }
}

和其他几个不同的尝试,我只是想不通怎么做。

编辑:

我会试着更好地解释一下。

我正在尝试将表格转换为列表,基本上就像计算机上的列表,列表标题和可排序项目以及中间的所有内容。使用

之类的命令启动表
$(this).list({
    data: [{id: 1, name:'My First List Item', date:'2010/06/26'}, {id:2, name:'Second', date:'2010/05/20'}]
});

.list<tbody>排序并执行其他一些初始任务,然后将以下方法添加到元素中:
.findItem(condition)允许您按条件查找某个项目(例如findItem('name == "Second"')
.list(condition)将列出与给定条件匹配的所有项目 .sort(key)将按给定的密钥对所有项目进行排序 等

这样做的最佳方法是什么?

3 个答案:

答案 0 :(得分:2)

如果您希望这些方法可以在任何jQuery对象上使用,则必须将它们中的每一个添加到jQuery的原型中。原因是每次调用$(".list")时都会创建一个新的对象,并且您附加到上一个此类对象的任何方法都将丢失。

将每个方法分配给jQuery的原型:

jQuery.fn.extend({
    list: function() { .. },
    findItem: function() { .. },
    sort: function() { .. }
});

这里的list方法很特殊,因为它可以两次调用。首先,在初始化列表时,第二,在按条件查找特定项目时。你必须以某种方式区分这两种情况 - 通过参数类型或其他一些参数。

如果为尚未使用list plugin初始化的对象调用这些方法,也可以使用data API抛出异常。首次调用('xyz').list({ .. })时,将一些状态变量存储在该对象的数据高速缓存中。当稍后调用任何其他方法 - “list”,“findItem”或“sort”时,检查对象是否在其数据高速缓存中包含该状态变量。

更好的方法是命名您的插件,以便list()将返回扩展对象。可以在其返回值上调用这三个扩展方法。界面如下:

$('selector').list({ ... });
$('selector').list().findOne(..);
$('selector').list().findAll(..);
$('selector').list().sort();

或者第一次保存对返回对象的引用,并直接调用它上面的方法。

var myList = $('selector').list({ ... });
myList.findOne(..);
myList.findAll(..);
myList.sort();

答案 1 :(得分:2)

我在这里找到了这个解决方案: http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html

这似乎完全符合我的需要。

(function($) {
    var TaskList = function(element, options)
    {
        var $elem = $(element);
        var options = $.extend({
            tasks: [],
            folders: []
        }, options || {});

        this.changed = false;
        this.selected = {};

        $elem.sortable({
            revert: true,
            opacity: 0.5
        });

        this.findTask = function(test, look) {
            var results = [];

            for (var i = 0,l = options.tasks.length; i < l; i++)
            {
                var t = options['tasks'][i];
                if (eval(test))
                {
                    results.push(options.tasks[i]);
                }
            }
            return results;
        }

        var debug = function(msg) {
            if (window.console) {
                console.log(msg);
            }
        }
    }

    $.fn.taskList = function(options)
    {
        return this.each(function() {
            var element = $(this);

            if (element.data('taskList')) { return; }

            var taskList = new TaskList(this, options);

            element.data('taskList', taskList);

        });
    }

})(jQuery);

然后我

    $('.task-list-table').taskList({
        tasks: eval('(<?php echo mysql_real_escape_string(json_encode($tasks)); ?>)'),
        folders: eval('(<?php echo mysql_real_escape_string(json_encode($folders)); ?>)')
    });
    var taskList = $('.task-list-table').data('taskList');

我可以使用taskList.findTask(condition);

由于构造函数有$elem,我还可以为list(condition)等方法编辑jQuery实例。这非常有效。

答案 2 :(得分:0)

this.each不需要。这应该做:

$.fn.list = function (options) {
    this.find = function(test) {
        //function logic
    };
    return this;
};

请注意,您将覆盖jQuery的本机find方法,不建议这样做。


另外,对于它的价值,我认为这不是一个好主意。假设jQuery实例只有从jQuery的原型对象继承的方法,因此我觉得你想要做的事情与普遍接受的jQuery-plugin行为不一致 - 即返回this对象(jQuery)实例)不变。