覆盖jQuery插件方法

时间:2013-12-16 21:12:23

标签: javascript jquery

我已经开始创建一个用于删除记录的jQuery插件。它将首先警告要删除记录的最终用户,然后从数据库中删除该记录并从页面中删除该行。

从页面中删除行的方法是complete()。通常,我需要从页面中删除几种方式中的行,或者甚至可能重定向到另一个页面。因此,我想将插件配置为使用其中一种方式,如果不存在,则可以完全覆盖complete()方法。

我的计划是让默认的complete()方法只调用另一个函数(即deleteMainRow()),并且在配置时,我只会更改要执行的函数(即deleteChildRow()

但是,尝试这样做时,我收到错误TypeError: this.deleteChildRow is not a function

如何做到这一点?

PS。虽然不是我的问题,虽然需要响应但不期望,但我对如何访问插件中的属性和方法感到困惑。正如我的脚本所示,我有时会将其作为this.someProperty访问,有时会将其作为settings.someProperty访问。另外,为了使事情有效,我需要将'elem'和'dialog'定义为全局变量,我不确定是否正确。任何建议将不胜感激。

谢谢

$(function() {

    $("#main_list tbody img.deleteListRecord").deleteRecord({
        serverGetRecord:'getDelete_account',
        serverDeleteRecord:'delete_account',
        getMessage  :function (data) {
            return '<p class="dialog-question">ARE YOU SURE YOU WANT TO DELETE THIS ACCOUNT?</p><h1 class="dialog-name">'+data.name+'</h1><p class="dialog-delete">'+h(data.address)+'</p><p class="dialog-location">'+h(data.location)+'</p>';
        },
        complete:function(){console.log(this);this.deleteChildRow();}
    });

});

(function($){
    //Used to delete records.  Will first warn enduser of the record to be deleted, and then delete the record from the database and remove the row from the page.
    var defaults = {
        //Server accessed using index.php?cid=123&controller=someController&task=someTask
        'url'               :'index.php',
        'cid'               :ayb.component.id,  //Default component ID for given page
        'controller'        :ayb.component.controller, //Default controller ID for given page
        'CSRF'              :ayb.CSRF,//CSRF to send to server for all POSTs
        'serverGetRecord'   :'getRecord', //Server method to get record data
        'serverDeleteRecord':'deleteRecord',//Server method to delete record data
        'getID'             :function () {  //Return ID of record.  User can override if different that this 
            return $(elem).parent().parent().data('id'); 
        },
        'complete'          :function () {  //User can select one of the pre-defined routines or completely override 
            deleteMainRow(); 
        },
        'userComplete'      :function () {},  //Any extra user-defined methods to call when complete 
        'buildMessage'      :function () {  //Create warning message.  Override if user doesn't want to get data from server.
            var t=this;
            $.get(this.url,{cid:this.cid,controller:this.controller,task:this.serverGetRecord,id:this.getID()},function (data){
                dialog.html((data.status==1)?t.getMessage(data):'Error getting delete information.');
                },'json'); 
        },
        'getMessage'        :function (data) {  //Get warning message.  User can override just getMessage and still use buildMessage 
            return '<p class="dialog-question">ARE YOU SURE YOU WANT TO DELETE THIS RECORD?</p>';
        }
    };

    //A couple of pre-defined delete completion routines
    var deleteMainRow=function(){
        $(elem).parent().parent().remove();
    }
    var deleteChildRow=function(){
        alert('deleteChildRow.');
    }
    var dialog; //Should I define this variable here?
    var elem; //Should I define this variable here?

    var methods = {
        init : function (options) {
            var settings = $.extend(defaults, options  || {});
            dialog=$('<div class="dialog-delete" title=""></div>')
            .appendTo('body')
            .dialog({
                autoOpen    : false,
                resizable   : false,
                height      : 300,
                width       : 440, 
                modal       : true,
                dialogClass : 'hide-title-bar',
                open: function(event, ui){settings.buildMessage()},
                buttons: [{
                    text    : 'YES, DELETE IT',
                    "class" : 'red',
                    click   : function() {
                        dialog.dialog('close');
                        $.post(this.url,{cid:settings.cid,controller:settings.controller,task:settings.serverDeleteRecord,CSRF:settings.CSRF,id:settings.getID()},function (status){
                            if(status==1){
                                settings.complete();
                                settings.userComplete();
                            }
                            else{alert('Error deleting record');}
                        });
                    }
                    },
                    {
                        text     : 'CANCEL',
                        "class"  : 'gray',
                        click    : function() {$(this).dialog("close");}
                    }
                ]
            });
            return this.each(function () {
                $(this).click(function(e) {
                    elem=this;
                    dialog.dialog('open');
                });
            });
        },
        destroy : function () {
            //Anything else I should do here?
            delete dialog;
            return this.each(function () {});
        }
    };

    $.fn.deleteRecord = function(method) {
        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.deleteRecord');
        }    
    };
    }(jQuery)
);

2 个答案:

答案 0 :(得分:1)

把这个:

$(function() {

    $("#main_list tbody img.deleteListRecord").deleteRecord({
        serverGetRecord:'getDelete_account',
        serverDeleteRecord:'delete_account',
        getMessage  :function (data) {
            return '<p class="dialog-question">ARE YOU SURE YOU WANT TO DELETE THIS ACCOUNT?</p><h1 class="dialog-name">'+data.name+'</h1><p class="dialog-delete">'+h(data.address)+'</p><p class="dialog-location">'+h(data.location)+'</p>';
        },
        complete:function(){console.log(this);this.deleteChildRow();}
    });

});

声明并调用模块后:)

因为你匿名呼叫甚至还没有创建的东西:)

答案 1 :(得分:0)

  • 创建一个闭包并保存原始插件以供将来重用;
  • 使用相同的名称重新创建插件;
  • 执行您想要的所有操作并调用原始插件。

    (function(){
        var originalPlugin = $.fn.pluginname;
    
        $.fn.pluginname = function(options) {
    
            var defaults = {
                someOption: 'string',
                anotherOption: { /* some object, if you need it ... */ },
                overridedfunction: function() { /* something */ }
            }
    
            var options = $.extend(defaults, options);
            var $this = $(this);
            $this.css('background-color', 'red'); // for example
    
            /* do something with '$this' applying any jquery */
    
            originalPlugin.apply(this, arguments);
        }
    })();