2010-01-12 6 views
69

Je suis un utilisateur jQuery relativement nouveau qui cherche à étendre un plugin jQuery existant qui fait environ 75% de ce dont j'ai besoin. J'ai essayé de faire mes devoirs à ce sujet. J'ai vérifié les questions suivantes sur stackoverflow:Meilleure façon d'étendre un plugin jQuery

J'ai read up sur la méthode extend. Cependant, tous ces devoirs m'ont laissé confus. Je travaille avec le plugin fullcalendar et j'ai besoin de modifier certains comportements ainsi que d'ajouter de nouveaux hooks d'événements. Suis-je coincé avec cela dans la fermeture du plugin lui-même? Est-ce que je manque quelque chose d'évident?

Idéalement, nous serions en mesure de séparer notre code du code plugin pour permettre une mise à niveau possible. Toute aide serait grandement appréciée, en particulier des indications sur les points où il me manque des informations ou des opinions sur la pertinence des solutions déjà présentées dans d'autres questions de Stack Overflow. Pour moi, ils se contredisent et je suis toujours confus.

+0

justkt, Pouvez-vous poster quelques exemples de code de la façon dont vous avez étendu le plugin fullcalendar? J'essaie actuellement de faire la même chose, mais je suis perplexe et je ne peux pas appeler les fonctions que j'ai soi-disant ajoutées. –

+0

@MattMcCormick - Avez-vous essayé la réponse acceptée ci-dessous? – justkt

+0

Ah, j'inclus .prototype. Je n'avais pas besoin de ça. Maintenant j'ai juste $ .extend (true, $ .fullCalendar, extensionMethods); et il fonctionne! Idéalement, je voudrais étendre l'objet Event mais ce n'est pas un espace de noms, donc je ne vois pas comment cela serait possible. Cela fonctionne pour l'instant cependant. –

Répondre

79

Je viens d'avoir le même problème en essayant d'étendre les plugins d'interface utilisateur jquery, et voici la solution que j'ai trouvé (trouvé par jquery.ui.widget.js):

 

(function($) { 
/** 
* Namespace: the namespace the plugin is located under 
* pluginName: the name of the plugin 
*/ 
    var extensionMethods = { 
     /* 
     * retrieve the id of the element 
     * this is some context within the existing plugin 
     */ 
     showId: function(){ 
      return this.element[0].id; 
     } 
    }; 

    $.extend(true, $[ Namespace ][ pluginName ].prototype, extensionMethods); 


})(jQuery); 

espérons que cette aide, s'il vous plaît demander si vous avez des questions.

+2

Donc, pour clarifier, si je voulais étendre la saisie semi-automatique de jQuery UI, alors 'Namespace' serait" ui "et le' pluginName' serait "autocomplete"? –

+1

Je pense avoir répondu à ma propre question. J'ai trouvé dans la source autocomplete où il appelle 'jQuery.widget (" ui.autocomplete ", ...)', et dans la source du widget où il se sépare au ".", Avec l'espace de noms étant l'index 0, et pluginName étant l'index 1. Donc, en d'autres termes, il semble que j'avais raison. :) –

+4

@Jared - J'ai fini par prendre votre avis ici pour étendre l'auto-complétion jQuery UI. Je décris mes objectifs ici: http://www.matthuggins.com/articles/extending-jquery-uis-autocomplete-to-improve-success, et j'ai le code complet ici: https://github.com/mhuggins/ jquery-ui-autocomplete-astuces. Si vous avez des suggestions d'amélioration, j'aimerais les entendre! –

2
$.fn.APluginName=function(param1,param2) 
{ 
    return this.each(function() 
    { 
     //access element like 
     // var elm=$(this); 
    }); 
} 

// sample plugin 
$.fn.DoubleWidth=function() 
    { 
    return this.each(function() 
     { 
     var _doublWidth=$(this).width() * 2; 
     $(this).width(_doubleWidth); 
     }); 
    } 

//

<div style="width:200px" id='div!'>some text</div> 

// en utilisant le plugin personnalisé

$('#div1').DoubleWidth(); 

/// ci-dessus dactylographié de utils travaillent habituellement des éléments dom ////// ///////// Utilitaires personnalisés

(function($){ 
    var _someLocalVar; 
    $.Afunction=function(param1,param2) { 
    // do something 
    } 
})(jquery); 

// accès ci-dessus util comme

$.Afunction(); 

// ce type de utils étendre habituellement javascript

+1

Ce n'est pas ce qu'il demande - il demande comment mieux prolonger un plugin déjà existant d'une manière qui permet de mettre à jour le plugin sous-jacent hes utilise comme base tout en ajoutant la fonctionnalité qu'il veut en plus. – prodigitalson

3

Ive a trouvé que, avec un grand nombre de plug-ins les méthodes sont protégées/privé (dans le cadre des fermetures). Si vous avez besoin de modifier la fonctionnalité des méthodes/fonctions, alors vous n'avez pas de chance, sauf si vous êtes prêt à le faire. Maintenant, si vous n'avez pas besoin de changer une de ces méthodes/fonctions alors vous pouvez utiliser $.extend($.fn.pluginName, {/*your methods/properties*/};

Une autre chose que j'ai fini par faire avant est simplement d'utiliser le plugin comme une propriété de mon plugin au lieu d'essayer de l'étendre.

Tout ce qui se résume à la façon dont le plugin que vous voulez étendre est codé.

+0

Dans l'extension principale est tout ce que je veux faire, mais dans certains cas, c'est comme ajouter des gestionnaires d'événements sur les éléments DOM créés à l'intérieur du plugin. Dans d'autres cas, je dois remplacer le comportement à l'intérieur des méthodes existantes. Plus je lis, moins je vois une façon propre de le faire. D'autres pensées? – justkt

+0

Eh bien, si ces mehods sont ceux de l'API publique (ce qu'ils ne semblent pas être), alors vous pouvez utiliser la méthode que j'ai mentionnée ci-dessus pour remplacer la définition de la fonction. A part ça, il n'y a pas de façon propre. Vous devrez juste le fourchonner pour vos usages et bidouiller. – prodigitalson

+2

@prodigitalson public * API;) – Nikhil

15

J'ai eu le même problème et suis venu ici, alors la réponse de Jared Scott m'a inspiré.

(function($) { 

    var fullCalendarOrg = $.fn.fullCalendar; 

    $.fn.fullCalendar = function(options) { 
     if(typeof options === "object") { 
      options = $.extend(true, options, { 
       // locale 
       isRTL: false, 
       firstDay: 1, 
       // some more options 
      }); 
     } 

     var args = Array.prototype.slice.call(arguments,0); 
     return fullCalendarOrg.apply(this, args); 
    } 

})(jQuery); 
1

Mon approche dans la réécriture des plugins jQuery a été de déplacer les méthodes et les variables qui doivent accéder aux options bloc et appeler le « étendre »

// in the plugin js file 
$.jCal = function (target, opt) { 
    opt = $.extend({ 
     someFunctionWeWantToExpose: function() { 
      // 'this' refers to 'opt', which is where are our required members can be found 
     } 
    } 

    // do all sorts of things here to initialize 

    return opt; // the plugin initialisation returns an extended options object 
} 


////// elsewhere ///// 

var calendar = $("#cal1").jCal(); 
calendar.someFunctionWeWantToExpose(); 
1

Exemple similaire à réponse Jared Scott`s , mais en faisant une copie du prototype d'objet original donne la possibilité d'appeler la méthode parent:

(function($) { 

    var original = $.extend(true, {}, $.cg.combogrid.prototype); 

    var extension = { 
     _renderHeader: function(ul, colModel) { 
      original._renderHeader.apply(this, arguments); 

      //do something else here... 
     } 
    }; 

    $.extend(true, $.cg.combogrid.prototype, extension); 

})(jQuery); 
0

jQuery Widget peut être étendu en utilisant jQuery Widget Factory.

(function ($) { 
    "use strict"; 

    define([ 
     "jquery", 
     "widget" 
    ], function ($, widget) { 
     $.widget("custom.yourWidget", $.fn.fullCalendar, { 
      yourFunction: function() { 
       // your code here 
      } 
     }); 

     return $.custom.yourWidget; 
    }); 
}(jQuery)); 

Découvrez jQuery Documentation pour en savoir plus:
Widget Factory API
Extending Widgets with the Widget Factory

Questions connexes