Как расширить плагин Twitter Bootstrap - PullRequest
45 голосов
/ 04 февраля 2012

Я копаюсь в Bootstrap в Твиттере и теперь хочу попробовать добавить некоторые функции в плагины, но я не могу понять, как это сделать.Используя модальный плагин в качестве примера (http://twitter.github.com/bootstrap/javascript.html#modals), Я хотел бы добавить новую функцию к плагину, которая может быть вызвана так же, как стандартные методы плагина. Я думаю, что наиболее близким является следующий код, но все, что я получаю, когда пытаюсь получить доступ, - это то, что функция не является частью объекта.

Есть предложения?1005 *

 $.extend($.fn.modal, { 
    showFooterMessage: function (message) { 
        alert("Hey"); 
    } 
}); 

Тогда я хотел бы назвать это следующим образом:

  $(this).closest(".modal").modal("showFooterMessage"); 

РЕДАКТИРОВАТЬ: ОК, я понял, как это сделать:

(function ($) {
    var extensionMethods = {
        displayFooterMessage: function ($msg) {
            var args = arguments[0]
            var that = this;

            // do stuff here
        }
    }

    $.extend(true, $.fn.modal.Constructor.prototype, extensionMethods);
})(jQuery);

Проблемас существующим набором плагинов Bootstrap является то, что если кто-то хочет расширить их, ни один из новых методов не может принимать аргументы. Моя попытка «исправить» это состояла в том, чтобы добавить принятие аргументов в вызове функции плагинов.

$.fn.modal = function (option) {
    var args = arguments[1] || {};
    return this.each(function () {
        var $this = $(this)
        , data = $this.data('modal')
        , options = typeof option == 'object' && option

        if (!data) $this.data('modal', (data = new Modal(this, options)))

        if (typeof option == 'string') data[option](args)
        else data.show()

    }) // end each
} // end $.fn.modal

Ответы [ 5 ]

35 голосов
/ 02 октября 2012

Это старая ветка, но я только что сделал несколько пользовательских расширений для модальных, используя следующий шаблон:

// save the original function object
var _super = $.fn.modal;

// add custom defaults
$.extend( _super.defaults, {
    foo: 'bar',
    john: 'doe'
});

// create a new constructor
var Modal = function(element, options) {

    // do custom constructor stuff here

     // call the original constructor
    _super.Constructor.apply( this, arguments );

}

// extend prototypes and add a super function
Modal.prototype = $.extend({}, _super.Constructor.prototype, {
    constructor: Modal,
    _super: function() {
        var args = $.makeArray(arguments);
        _super.Constructor.prototype[args.shift()].apply(this, args);
    },
    show: function() {

        // do custom method stuff

        // call the original method
        this._super('show');
    }
});

// override the old initialization with the new constructor
$.fn.modal = $.extend(function(option) {

    var args = $.makeArray(arguments),
        option = args.shift();

    return this.each(function() {

        var $this = $(this);
        var data = $this.data('modal'),
            options = $.extend({}, _super.defaults, $this.data(), typeof option == 'object' && option);

        if ( !data ) {
            $this.data('modal', (data = new Modal(this, options)));
        }
        if (typeof option == 'string') {
            data[option].apply( data, args );
        }
        else if ( options.show ) {
            data.show.apply( data, args );
        }
    });

}, $.fn.modal);

Таким образом, вы можете

1) добавить свои собственные параметры по умолчанию

2) создавать новые методы с пользовательскими аргументами и доступом к оригинальным (супер) функциям

3) делать вещи в конструкторе до и / или после вызова исходного конструктора

28 голосов
/ 12 февраля 2013

Для записи существует простой способ переопределить или расширить существующие функции:

var _show = $.fn.modal.Constructor.prototype.show;

$.fn.modal.Constructor.prototype.show = function() {
    _show.apply(this, arguments);
    //Do custom stuff here
};

Не распространяется на пользовательские аргументы, но это легко сделать с помощью метода выше; вместо использования apply и arguments укажите исходные аргументы плюс пользовательские аргументы в определении функции, затем вызовите исходный _show (или какой бы то ни было) с исходными аргументами и, наконец, сделайте другие вещи с новым аргументы.

4 голосов
/ 18 апреля 2012

Для справки, у меня была похожая проблема, поэтому я "расширил" плагин Typeahead , разветвив и добавив нужные мне функции в самом скрипте плагина.

Если вам нужно изменить исходный код, это на самом деле не расширение, так что я решил, что было бы проще просто собрать все мои модификации в одном месте.

2 голосов
/ 06 июля 2015

+ 1 за принятый выше ответ от Дэвида. Но если бы я мог упростить это немного больше, я бы настроил расширение DEFAULTS и расширение $fn.modal следующим образом:

!function($) {

    'use strict';

    // save the original function object
    var _super = $.fn.modal;

    // create a new constructor
    var Modal = function(element, options) {

        // do custom constructor stuff here

        // call the original constructor
        _super.Constructor.apply( this, arguments );

    }

    // add custom defaults
    Modal.DEFAULTS = $.extend( _super.defaults, {
         myCustomOption: true
    });

    // extend prototypes and add a super function
    Modal.prototype = $.extend({}, _super.Constructor.prototype, {
        constructor: Modal,
        _super: function() {
            var args = $.makeArray(arguments);
            _super.Constructor.prototype[args.shift()].apply(this, args);
        },
        show: function() {

            // do custom method stuff

            // call the original method
            this._super('show');
        },
        myCustomMethod: function() {
            alert('new feature!');
        }
    });

    // Copied exactly from Bootstrap 3 (as of Modal.VERSION  = '3.3.5')
    // Notice: You can copy & paste it exactly, no differences!
    function Plugin(option, _relatedTarget) {
        return this.each(function () {
            var $this   = $(this)
            var data    = $this.data('bs.modal')
            var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)

            if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
            if (typeof option == 'string') data[option](_relatedTarget)
            else if (options.show) data.show(_relatedTarget)
        })
    }

    // override the old initialization with the new constructor
    $.fn.modal = $.extend(Plugin, $.fn.modal);

}(jQuery);
2 голосов
/ 30 сентября 2013

Для тех, кто хочет сделать это с помощью Bootstrap 3. Компоновка плагина немного изменилась, к конструктору плагинов добавлены параметры по умолчанию для всех плагинов Bootstrap 3:

var _super = $.fn.modal;
$.extend(_super.Constructor.DEFAULTS, {
       foo: 'bar',
       john: 'doe'
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...