2011-03-12 2 views
1

Я хотел бы сделать подклассовую оболочку jQuery, которая имеет все методы jQuery, плюс еще несколько. Я также хотел бы переопределить некоторые методы jQuery. Вот пример того, что я хотел бы достичьПодкласс объекта jQuery

calendar('.cal').showPopup() 
        .selectDate(new Date()) 
        .addClass('popup-visible'); 
    alert(calendar.val()); 

Обратите внимание, что календарь работает точно так же, как объект JQuery кроме

  • Он имеет некоторые дополнительные методы (showPopup и selectDate)
  • It имеет переопределенный метод (val)
  • При использовании цепочки методов возвращается объект Calendar. Это означает, что addClass не должен возвращаться к объекту jQuery.

Буду признателен, если кто-то сообщит мне в правильном направлении. Я играл с областями и $ .extend и прототипами, но, похоже, не мог заставить ничего работать.

Спасибо!

ответ

4

Оказывается, что JQuery 1,5 имеет новый метод, называемый суб :)

Согласно документации, к югу

создает новую копию JQuery, свойства и методы могут быть изменены без влияния оригинальный объект jQuery. http://api.jquery.com/jQuery.sub/

Этот метод не позволяет создать подкласс подкласса, но я нашел модифицированный метод в своем трекере билет, который позволил это:

jQuery.subclass = function(){ 
    function jQuerySubclass(selector, context) { 
    return new jQuerySubclass.fn.init(selector, context); 
    } 
    jQuery.extend(true, jQuerySubclass, this); 
    jQuerySubclass.superclass = this; 
    jQuerySubclass.fn = jQuerySubclass.prototype = this(); 
    jQuerySubclass.fn.constructor = jQuerySubclass; 
    jQuerySubclass.fn.init = function init(selector, context) { 
    if (context && context instanceof jQuery && !(context instanceof jQuerySubclass)){ 
     context = jQuerySubclass(context); 
    } 
    return jQuery.fn.init.call(this, selector, context, rootjQuerySubclass); 
    }; 
    jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; 
    var rootjQuerySubclass = jQuerySubclass(document); 
    return jQuerySubclass; 
}; 

Это позволяет сделать что-то вроде этого:

var Calendar = jQuery.subclass(); 
Calendar.create = function() { 
    var cal = Calendar(/* some html code for building the calendar */); 

    // Do some processing like binding events, etc 

    return cal; 
} 
Calendar.fn.val = function(value) { 
    //Calendar's implementation of val 
} 

объект Calendar будет действовать точно так же, как объект JQuery кроме для тех выше различий. Он также правильно вернет экземпляр Календаря, когда я объединю методы вместе. Это аккуратное, потому что

  • Мы можем легко создавать собственные виджеты без загромождения пространства имен JQuery .
  • Мы можем предоставить наши собственные реализации методов JQuery
  • Мы можем использовать силы JQuery с методами, как спусковой крючок и связать уже часть класса

Далее, я заинтересован в разрешении классов, чтобы быть зарегистрированный селектором. Таким образом, когда вы вызываете $ ('. MyAwesomeCalendar'), вы вернете объект Calendar без явного вызова Calendar ('. MyAwesomeCalendar').

+0

для вашего последнего комментария, о наличии разных подклассов, назначенных классом css, вы ищете что-то более чистое, чем переопределение $ .fn.init? – NullVoxPopuli

1

Я собираюсь начать с того, что думаю, что вы должны немного углубиться в способ плагина jQuery $.fn. Вы можете прочитать об этом здесь:

http://docs.jquery.com/Plugins/Authoring

Я выполнил бы выше, как это:

(function($){ 
    $.fn.calendar = function(){ 
    //do something useful 
    return this; // necessary for chaining 
    }; 
    $.fn.calendar.showPopup = function(){ 
    //do something useful 
    return this; //necessary for chaining 
    } 
)(jQuery); 

Так что, как говорится. В приведенном выше примере вам понадобится аналогичный синтаксис для возврата jQuery в вашу функцию calendar, и для этого потребуется вернуть Календаря, чтобы обеспечить цепочку. Я не могу доказать этот код ниже, но это хорошее начало:

var Calendar = (function($){ 
    calendar = { 
    showPopup : function($){ 
     //do something useful 
     return $; //required for chaining 
    }, 
    val : function($){ 
     //return your inherent functionality 
     return $; //required for chaining 
    } 

    } 
}); 
var calendar = new Calendar(jQuery); 

Как я уже сказал, это некрасиво и не совсем, как это должно быть сделано.

Я не эксперт по javascript, но я считаю, что это так. Я также приветствую любую критику.

+0

Спасибо за ответ, но я искал способ, который позволил полиморфизму. Например, новый виджет, который я создал, будет иметь другую реализацию val(). –

+0

Не беспокойтесь. Вышеупомянутый ответ звездный и удивил меня - я не видел эту функцию в новой документации 1.5. Похоже, это именно то, что вы хотите! – philwinkle