Продвинутая теория создания плагинов

Прошлый раз я рассказал вам о замечательной библиотеке Raphaël и о том как хорошо и удобно с ней работать, в этот раз я не буду останавливаться на таких подробностях и расскажу о продвинутой теории реализации плагина который позволяет рисовать векторную графику поверх растровой будет взаемодействовать с другими плагинами.

По результатам плагина autocomplete я остался очень доволен подходом создания call-back функций в основных методах плагина, они дают пользователю (программисту) дописать функционал не меняя код плагина, тоесть навешивать бизнес логику приложения не мешая ее с логикой плагина. Опыт того же autocomplete показал мне, что когда плагин пишется в закрытом пространстве имен и не присваивается ноде к которой имеет отношение, то есть проблемы с тем чтобы передать плагину какие-то данные или выполнить какие-то действия над ним снаружи, смотрите что я имею ввиду:


(function($) {
    var Plugin = function (elt, opt) {
        this.init(elt, opt);
    };

    Plugin.prototype = {
    };

    $.fn.plugin = function(options) {
        this.each(function() {
            //this.plugin = new Plugin(this, options);
            new Plugin(this, options);
        });
        return this;
    };

})(jQuery);

// если бы я сохранял инстанс в ноде, можно было бы использовать его, но я так не делаю
$("selector").plugin({/**/});
$("selector").get(0).plugin.someMethod(params);

На этот раз я решил это очень элегантным способом создав для плагина несколько событий, более того ничто не мешает добавить свое собственное событие через call-back onInit


    Plugin.prototype = {
        onInit : function(){},
        init : function (elt, opt){
            $(elt).bind("eventName", this, function(e, params){
                var self = e.data; // Plugin
                // some code
            })
	    this.onInit.apply(this, arguments);
        }
    };

$("selector").plugin({
    onInit : function(/*params*/){
        var self = this;  // Plugin
        // some code
    }
});
// some code
$("selector").trigger("eventName", [param1, param2]);

Теперь плагин имеет двустороннее общение с внешним миром и в него можно как передавать данные так и забирать полученный результат, от того сколько и каких событий и call-back’ов будет в вашем плагине зависит его гибкость. Теоритически уже даже тот пример который я привел можно превратить в небольшой плагин без логики в нутри :)