2009-12-10 5 views
0

J'ai commencé par cette question: Multiple Javascript gadgets per page. Après avoir lu sur la façon de construire un plugin jQuery J'ai modifié mon OO objet JavaScript dans un plugin jQuery en enveloppant mon objet JS dansQuelle est l'approche OO pour accéder aux méthodes du plugin jQuery à partir de mon plugin HTML?

(function {} { /*my object code*/ }(jQuery)) 

et en ajoutant un

function createMyGadget() { return new myObject } 

dans mon objet. Je peux maintenant afficher avec succès deux gadgets sur une page en procédant comme suit:

<div id="foo"></div> 
<div id="bar"></div> 

<script language="JavaScript"> 
    $("#foo").createMyGadget({ title: "My First Gadget"}); 
    $("#bar").createMyGadget({ title: "My Second Gadget"}); 
</script> 

Dans le cadre de la fonction createMyGadget(), je crée un nouveau div avec un identifiant unique (gadgetUID), écrire un tas de HTML, des boutons, imgs, etc. à ce div, puis ajouter ce div à #foo et #bar. Cela fonctionne bien.

Dans mon code HTML, j'ai un bouton "Suivant" qui doit appeler la fonction goNext() qui est définie dans l'objet JavaScript. Comment puis-je référencer cette fonction dans cet objet? J'ai essayé

onClick='$("#foo").goNext()' 

et

onClick='$("#gadgetUID").goNext()' 

et toutes les autres permutations que je pouvais penser. Firebug répond toujours avec un message d'erreur "... pas une fonction".

ADDENDA: Voilà ma réponse à johnnyheadphones:

J'ai essayé de faire la même chose à l'intérieur de jQuery avec les mêmes résultats, par exemple '... n'est pas une fonction'. Voici l'appel de fonction réelle:

displayGadget : function() { 

    var myString = "\ 
    <div id=\""+this.gadgetId+"\" >\ 
     <div id=\"gadget_header\">\ 
      <h1 id=\"title\">"+this.options.title+"</h1>\ 
     </div>\ 
     <div id='loading' style=''><img src='images/loading2.gif' /></div> \ 
     <div id=\"gadget_body\"></div>\ 
     <div id=\"gadget_footer\">\ 
      <div id=\"searchAsset\">\ 
      </div>\ 
      <div id=\"pageControls\">\ 
       <img id=\"goPreviousIcon\" src=\"images/go-previous.png\">\ 
       <img id=\"goNextIcon\" src=\"images/go-next.png\">\ 
       <input type=\"button\" value=\"Next\" />\ 
      </div>\ 
     </div> \ 
    \ 
    </div>\ 
    <div id=\"debugInfo\"></div>\ 
      <script type=\"text/javascript\"> \ 
      </script>\ 
    "; 

    $("#"+this.gadgetContainerID).html(myString); 

    $('input[value="Next"]','#'+this.gadgetContainerID).click(function() { 
     $('#'+this.gadgetId).pageData(1); 
    }); 
} 

Lorsque je recharge et cliquez sur le bouton suivant, Firebug dit '$ (' # '+ this.gadgetId) .pageData (1) n'est pas une fonction.

BTW, je voulais initialement faire cela avec le goNextIcon, mais l'a changé en un bouton afin que je puisse copier/coller votre code. Je commence à penser que j'ai quelque chose d'autre faux et c'est juste un sous-produit étrange.

ADDENDUM: J'ai trouvé le problème: je suis un idiot (mais n'importe lequel de mes xGF pourrait vous l'avoir dit). J'appelais le pageData() sur l'élément en question

Il n'y a pas de fonction pageData() sur l'élément; c'est sur l'objet 'this'. Onc j'ai pointé vers le bon (et seulement) objet pageData() (qui est attaché à 'ceci'), cela a fonctionné comme annoncé.

Maintenant, pour faire un peu de nettoyage de code.

+0

Lire le dernier message d'erreur comme "... pageData (1) n'est pas une fonction". Aviez-vous vraiment l'intention d'appeler une méthode "pageData"? C'est juste pas défini. – Frunsi

Répondre

1

si vous écrivez le gestionnaire onclick dans le cadre du code HTML qui est ajouté au DOM, essayer quelque chose comme ceci:

<input type="button" value="Next" onclick="function() { $('#gadgetUID').goNext(); }" /> 

Ou, vous pouvez utiliser jQuery pour lier le gestionnaire à l'intérieur du code de plug-in. Sans voir un échantillon de code, il est difficile de dire exactement ce dont vous avez besoin. Mais ceci est l'idée générale:

$('input[value="Next"]','#foo').click(function() { 
    $('#gadgetUID').goNext(); 
}); 

EDIT: On dirait que c'est un problème de cadrage. Appeler pageData() dans la portée correcte devrait résoudre votre problème. Peut-être quelque chose comme ça fonctionnerait:

displayGadget : function() { 
    // encapsulate this in a closure, so pageData() is called on the instance 
    // of the object, not the DOM element selected by jQuery 
    var that = this; 

    [... string stuff here. you should replace 'this' with 'that' here as well ...] 

    $("#"+that.gadgetContainerID).html(myString); 

    $('#goNextIcon','#'+that.gadgetContainerID).click(function() { 
     that.pageData(1); 
    }); 
}, 

// the above code assumes that pageData() is part of the same 
// object instance as displayGadget. if not, then you'll have to 
// tweak your code to point call pageData in the correct scope 
pageData: function(page) { 
    // do stuff here! 
} 

Notez que j'ai changé le sélecteur jQuery retour en fonction de votre code d'origine (les balises d'image).

Si vous prévoyez d'avoir plusieurs instances de ce code HTML sur une page, une chose que vous voudrez peut-être à considérer est l'utilisation des classes au lieu d'ID pour les éléments DOM générés. Donner le même identifiant à plus d'un élément DOM est généralement une mauvaise chose et peut vous causer des maux de tête et des bugs plus tard.

, vous pouvez également regarder dans la création de nœuds DOM au lieu d'utiliser innerHTML pour générer les commandes. Il serait plus facile de conserver des références aux éléments et d'y attacher des gestionnaires d'événements.

+0

Voir ma réponse à vous dans mon message. – user63741

+0

Où est défini pageData()? est-ce une méthode du même objet qui a displayGadget()? si c'est le cas, puis vérifiez la modification de mon message. – jonnyheadphones

+0

Oui, pageSata() est défini dans le même objet (via .prototype) que displayGadget(). Je suis d'accord que c'est un problème de portée mais toutes les méthodes sont publiques, donc WTF? Je ne vois rien dans votre soln que je n'ai pas déjà essayé, mais je vais essayer encore une fois le matin. Merci pour le rappel de passer des identifiants aux classes. Je voulais faire ça avant de commencer à lutter avec les alligators. – user63741

0

Peut-être est ce que vous pensez ...

onClick = function() { 
    $("#gadgetUID").goNext(); 
} 

Cela crée une référence à une fonction anonyme qui trouve votre objet JQuery (s) et exécute la fonction que vous souhaitez exécuter.

+0

Cela, et chaque permutation que j'ai essayé, me donne une erreur de syntaxe – user63741

Questions connexes