javascript - instalar - jquery slim
adjuntando una clase a un objeto jQuery (1)
Estoy luchando con la mejor manera de combinar las clases de JavaScript y los complementos de jQuery. Esta pregunta no es muy específica, lo que estoy esperando es punteros a más recursos.
Básicamente, quiero almacenar datos de estado y métodos privados en una clase, y luego extender cada objeto jQuery al que llamo mi complemento para tener esos métodos y propiedades privados. Tal que dentro del complemento puedo llamar a métodos directamente desde el objeto jQuery.
Leo el patrón de diseño de jQuery plugin (¿práctica común?) Para tratar con funciones privadas , específicamente la respuesta de David, sin embargo, esto inicializa una nueva Clase cada vez, y por lo tanto no puede usarse para guardar el estado del objeto.
También encontré http://fuelyourcoding.com/jquery-plugin-design-patterns-part-i/ , que recomienda crear una clase y luego almacenarla en .data ().
Creo que idealmente, con lo que quiero terminar es con un código que se parece a
(function( $ ){
var methods = {
init : function( options ) { // Initialize each object with a state and private methods },
show : function( ) {
// testFoo() is a private method that checks the element''s state
if(this.testFoo()){
// Relying on jQuery''s html() method
this.html() = this.fooTemplate();
}
}
};
// Boiler plate plugin from http://docs.jquery.com/Plugins/Authoring
$.fn.myPlugin = function( method ) {
// Method calling logic
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.myPlugin'' );
}
};
})( jQuery );
Finalmente, no parece que pueda hornear los métodos privados en el complemento directamente porque los métodos como "testFoo ()" devolverán un booleano, y por lo tanto no son encadenables.
¿Pensamientos? ¿Me estoy acercando a esto de la manera correcta? ¿Hay algún otro patrón de diseño que debería usar? ¿Quizás no usar la arquitectura del complemento jQuery?
Aquí hay una solución propuesta. Combina algunos enfoques diferentes (el modelo de herencia de John Resig y el modelo de herencia de complementos de Alex Saxton).
Defina su plugin heredable:
(function ($) {
My.Plugin = Class.extend({
/*
* Initialization (constructor)
*/
init: function (element, meta) {
var $meta = $.extend({ name: "pluginName" }, meta);
// Call the base constructor
this._super(element, $meta);
// TODO: Add custom initialization code like the following:
// this._testButton = $(''.testButton'', element).get(0);
},
/*
* Public methods
*/
show: function() {
alert(''This is a public method'');
},
/*
* Private methods
*/
// DEMO: Overriding the base _paint method:
_paint: function () {
// "this._super()" is available in all overridden methods
// and refers to the base method.
this._super();
alert(''TODO: implement myPlugin._paint!'');
}
});
// Declare this class as a jQuery plugin
$.plugin(''my_plugin'', My.Plugin);
})(jQuery);
Definir clase Base
(function () {
var initializing = false, fnTest = /xyz/.test(function () { xyz; }) ? //b_super/b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function () { };
// Create a new Class that inherits from this class
Class.extend = function (prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don''t run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we''re overwriting an existing function
prototype[name] =
typeof prop[name] == "function"
&& typeof _super[name] == "function"
&& fnTest.test(prop[name])
? (function (name, fn) {
return function () {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we''re done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name])
: prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.init)
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
Creación de plugins
(function ($) {
// The "inheritance plugin" model
// [http://alexsexton.com/?p=51][1]
$.plugin = function (name, object) {
$.fn[name] = function (options) {
var instance = $.data(this, name, new object(this, options));
return instance;
};
};
})(jQuery);
Llamar a tu complemento desde javascript:
$(''#someElem'').my_plugin({options: {}, data: {} /* you can modify your plugin code to accept anything */}).show();
Nota:
Los métodos privados aquí están marcados como _methodName. Es pura convención. Si realmente desea ocultarlos, puede usar el patrón del módulo (google para él o aquí hay uno para empezar: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth )
Es esto lo que estás buscando?