2013-12-16 10 views
1

Я принял удар по созданию плагина 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) 
); 

ответ

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();} 
    }); 

}); 

После того как модуль объявлен и называется :)

Потому что вы звоните анонимно, что даже не было еще создано :)

+0

Благодаря Holybreath. Вы имеете в виду просто загрузить плагин первым, не так ли? Я пытался это сделать, но никаких изменений. Не думайте, что это имеет значение, но я загружаю ' 'где main.js имеет скрипт, на который вы ссылаетесь. – user1032531

+0

При дальнейшем тестировании он работает, если я заменил 'this.deleteChildRow()' на 'deleteChildRow()'. Остаток моего плагина выглядит достаточно хорошо написанным? Еще раз спасибо – user1032531

+0

Я думаю, что в этом контексте это полный метод, а не ваш плагин, будьте осторожны с контекстом :). Мое личное предпочтение для метода .each - .each (function (i, current) {}), потому что опять же, вы бы хотели использовать меньше «этого» везде, если вы не полностью уверены в контексте, «текущий» - это текущий элемент, довольно удобный ... :) – Holybreath

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); 
        } 
    })(); 
    
Смежные вопросы