2009-03-30 7 views
1

J'essaye de créer un plugin jQuery, à l'intérieur j'ai besoin de faire un appel AJAX pour charger un xml.Ajax appel dans un plugin jQuery ne fonctionne pas correctement

jQuery.fn.imagetags = function(options) { 

    s = jQuery.extend({ 
    height:null, 
    width:null, 
    url:false, 
    callback:null, 
    title:null, 
    }, options); 

    return this.each(function(){ 
    obj = $(this); 

    //Initialising the placeholder 
    $holder = $('<div />') 
    .width(s.width).height(s.height) 
    .addClass('jimageholder') 
    .css({ 
     position: 'relative', 
    }); 
    obj.wrap($holder); 

    $.ajax({ 
     type: "GET", 
     url: s.url, 
     dataType: "xml", 
     success:function(data){ initGrids(obj,data,s.callback,s.title); } , 
     error: function(data) { alert("Error loading Grid data."); }, 
    }); 

    function initGrids(obj, data,callback,gridtitle){ 
    if (!data) { 
     alert("Error loading Grid data"); 
    } 

    $("gridlist gridset",data).each(function(){ 
     var gridsetname = $(this).children("setname").text(); 
     var gridsetcolor = ""; 
     if ($(this).children("color").text() != "") { 
     gridsetcolor = $(this).children("color").text(); 
     } 
     $(this).children("grid").each(function(){  
     var gridcolor = gridsetcolor; 
     //This colour will override colour set for the grid set 
     if ($(this).children("color").text() != "") { 
      gridcolor = $(this).children("color").text(); 
     } 

     //addGrid(gridsetname,id,x,y,height,width) 
     addGrid(
      obj, 
      gridsetname, 
      $(this).children("id").text(), 
      $(this).children("x").text(), 
      $(this).children("y").text(), 
      $(this).children("height").text(), 
      $(this).children("width").text(), 
      gridcolor, 
      gridtitle 
     ); 

     }); 
    }); 

    } 

    function addGrid(obj,gridsetname,id,x,y,height,width,color,gridtitle){ 
     //To compensate for the 2px border 
     height-=4; 
     width-=4; 

     $grid = $('<div />') 
     .addClass(gridsetname) 
     .attr("id",id) 
     .addClass('gridtag') 
     .imagetagsResetHighlight() 
     .css({ 
     "bottom":y+"px", 
     "left":x+"px", 
     "height":height+"px", 
     "width":width+"px", 
     }); 
     if(gridtitle != null){ 
     $grid.attr("title",gridtitle); 
     } 

     if(color != ""){ 
     $grid.css({ 
     "border-color":color, 
     }); 
     } 
     obj.after($grid); 
    } 
    }); 
} 

Le plugin ci-dessus je lie avec 2 objets DOM et charges deux fichiers XML séparés, mais la fonction de rappel est exécutée uniquement sur le dernier objet DOM à l'aide des deux fichiers XML chargés.

Comment puis-je résoudre ce problème, afin que le rappel soit appliqué sur les DOM correspondants. L'appel ajax ci-dessus est-il correct?

Exemple d'utilisation:

<script type="text/javascript"> 
     $(function(){ 
      $(".romeo img").imagetags({ 
       height:500, 
       width:497, 
       url: "sample-data.xml", 
       title: "Testing...", 
       callback:function(id){ 
       console.log(id); 
       }, 
      }); 
     }); 
     </script> 
     <div class="padding-10 min-item background-color-black"> 
     <div class="romeo"><img src="images/samplecontent/test_500x497.gif" alt="Image"> </div> 
     </div> 

<script type="text/javascript"> 
     $(function(){ 
      $(".romeo2 img").imagetags({ 
       height:500, 
       width:497, 
       url: "sample-data2.xml", 
       title: "Testing...", 
       callback:function(id){ 
       console.log(id); 
       }, 
      }); 
     }); 
     </script> 
     <div class="padding-10 min-item background-color-black"> 
     <div class="romeo2"><img src="images/samplecontent/test2_500x497.gif" alt="Image"> </div> 
     </div> 

Voici l'échantillon des données XML:

<?xml version="1.0" encoding="utf-8"?> 
<gridlist> 
    <gridset> 
     <setname>gridset4</setname> 
     <color>#00FF00</color> 
     <grid> 
     <color>#FF77FF</color> 
     <id>grid2-324</id> 
     <x>300</x> 
     <y>300</y> 
     <height>60</height> 
     <width>60</width> 
    </grid> 
    </gridset> 
    <gridset> 
     <setname>gridset3</setname> 
     <color>#00FF00</color> 
     <grid> 
     <color>#FF77FF</color> 
     <id>grid2-212</id> 
     <x>300</x> 
     <y>300</y> 
     <height>100</height> 
     <width>100</width> 
    </grid> 
    <grid> 
     <color>#FF77FF</color> 
     <id>grid2-1212</id> 
     <x>200</x> 
     <y>10</y> 
     <height>200</height> 
     <width>10</width> 
    </grid> 
    </gridset> 
</gridlist> 
+0

Pouvez-vous fournir plus d'informations? La syntaxe semble correcte (sauf pour le ',' final), mais sans regarder comment vous liez, ou l'objet s je ne peux pas en dire beaucoup plus. – Joel

Répondre

0

Vous pourriez éprouver des problèmes parce que votre appel la charge ajax sur la même URL, donc le second appel annule la première appel.

Si vous lisez dans le même URL pour chaque div, pourquoi n'appelez-vous pas l'ajax une fois alors boucle les éléments quand il revient. Fondamentalement, ce que vous faites ici appelle la fonction ajax puis retourne instantanément l'ensemble. Ensuite, lorsque le rappel ajax est déclenché, vous faites une boucle sur les éléments et ajoutez les données.

+0

J'ai essayé d'utiliser une variable. Le résultat est le même :( – Saneef

+0

J'appelle l'AJAX sur 2 URLs différentes – Saneef

+0

du code que je vois il ressemble à votre appel ajax sur le même s.url pour chaque objet – bendewey

0

Cela peut être un problème de portée. Vous devez utiliser l'instruction 'var' lors de la déclaration des variables dans les fonctions. Sinon, les variables entrent dans la portée globale.

var s = jQuery.extend({ 
    height:null, 
    width:null, 
    url:false, 
    callback:null, 
    title:null, 
    }, options); 

elems.each(function() {  
     var obj = $(this); 

     .... 
} 

Comme les variables vivent dans la portée globale, ils seront écrasés par chaque itération dans la boucle, et, finalement, entraînant le dernier élément DOM.

Questions connexes