Ajax-вызов в плагине jQuery не работает должным образом - PullRequest
1 голос
/ 30 марта 2009

Я пытаюсь создать плагин jQuery, внутри мне нужно сделать AJAX-вызов для загрузки xml.

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);
    }
  });
}

Вышеупомянутый плагин я связываю с двумя объектами DOM и загружает два отдельных файла XML, но функция обратного вызова запускается только для последнего объекта DOM, используя оба загруженных файла XML.

Как это исправить, чтобы обратный вызов был применен к соответствующим DOM. Является ли приведенный выше вызов ajax правильным?

Пример использования:

<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>

Вот пример данных 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>

Ответы [ 2 ]

0 голосов
/ 15 декабря 2009

Возможно, это проблема с областью видимости. Вы должны использовать оператор 'var' при объявлении переменных внутри функций. В противном случае переменные попадают в глобальную область видимости.

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

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

      ....
}

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

0 голосов
/ 30 марта 2009

Возможно, у вас возникли проблемы, потому что ваш вызов ajax загружается по тому же URL-адресу, поэтому второй вызов отменяет первый вызов.

Если вы читаете по одному и тому же URL для каждого div, почему бы вам не вызвать ajax один раз, а затем зациклить элементы, когда он вернется.

jQuery.fn.imagetags = function(options) {

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

  var elems = $(this);

  $.ajax({
      type: "GET",
      url: s.url,
      dataType: "xml",
      success:function(data){ 
        elems.each(function() {     
          obj = $(this);

          //Initialising the placeholder  
          $holder = $('&lt;div /&gt;')
          .width(s.width).height(s.height)
          .addClass('jimageholder')
          .css({
              position: 'relative',
          });
          obj.wrap($holder); 
          initGrids(obj,data,s.callback,s.title); 
        });
      },
      error: function(data) { alert("Error loading Grid data."); }
    });

  return $(this);
}

По сути, то, что вы делаете здесь, вызывает функцию ajax, а затем мгновенно возвращает набор. затем, когда вызывается обратный вызов ajax, вы зацикливаете элементы и добавляете данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...