Асинхронные загрузки страниц. Как передать параметры в функции обратного вызова? - PullRequest
0 голосов
/ 06 апреля 2009

Часть асинхронного обратного вызова jQuery / ajax по-прежнему ставит меня в тупик, и я уверен, что это только потому, что я недостаточно хорошо знаю javascript.

Упрощение кода настолько, насколько это возможно, вот где я застрял:

Если я создаю пустой div с идентификатором "queuediv1", я могу заполнить его результатами метода страницы, подобного этому.

$(document).ready(function() { 
    $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      url: "test12.aspx/GetHtmlTest", 
      //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
      data: "{}", 
      // Error! 
      error: function(xhr, status, error) { 
          // Boil the ASP.NET AJAX error down to JSON. 
          //var err = eval("(" + xhr.responseText + ")"); 

          // Display the specific error raised by the server 
          //alert(err.Message); 
          alert("AJAX Error!"); 
      }, 
       success: function(msg) { 
        $("#queuediv1").removeClass('isequeue_updating'); 
        $("#queuediv1").html(msg); 
            //an unorderd list with the tag "browserxx" was just inserted into the div 
        $("#browserxx").treeview(); 
      } 
    }); 
}); 

Это прекрасно работает; это не блокирует, и это дает мне полный контроль над обработкой ошибок. Однако, когда я пытаюсь расширить это, у меня возникают проблемы. Если у меня есть несколько областей страницы, которые я хочу обновить, я могу изменить вызов так, чтобы каждый асинхронный вызов выполнялся с правильными «данными», но я не могу сказать обратному вызову идентификатор элемента управления, который мне нужен. заселить.

Упрощение моего дела до чего-то, что все еще сломано:

Предположим, в DOM есть 4 div, которые я хочу обновить с помощью идентификатора queuediv1, queuediv2, queuediv3 и queuediv4. Я хотел бы использовать как можно больше кода. Хотя число и идентификаторы div, которые будут обновлены, на самом деле будут динамическими, я подумал, что это сработало бы:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
     var divname ="#queuediv"+i; 

    $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      url: "test12.aspx/GetHtmlTest", 
      // data would be populated differently so that each div gets its own result- for now it doesn't matter 
      //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
      data: "{}", 
      // Error! 
      error: function(xhr, status, error) { 
          // Boil the ASP.NET AJAX error down to JSON. 
          //var err = eval("(" + xhr.responseText + ")"); 

          // Display the specific error raised by the server 
          //alert(err.Message); 
          alert("AJAX Error!"); 
      }, 
       success: function(msg) { 
        $(divname).removeClass('isequeue_updating'); 
        $(divname).html(msg); 
        $("#somethingfromthemsg").treeview(); 
      } 
    }); 
} 
}); 

Но это не может сработать, так как к тому времени, когда успех называется областью действия, это неверно, а divname уже равно "# queuediv4" для каждого обратного вызова. Только этот div обновляется (4x). Есть ли способ передать переменную в обратный вызов? Или я просто думаю о проблеме неправильно.

Я нашел что-то похожее на асинхронные вызовы $ .getJSON здесь: http://thefrontiergroup.com.au/blog/tag/jquery

На этом сайте говорилось об обёртывании обратного вызова внутри другой анонимной функции для сохранения вызывающих переменных. Это имело смысл для области видимости, но я не представляю, как создать способ вызова $ .ajax.

Ответы [ 3 ]

1 голос
/ 06 апреля 2009

Помните, что JavaScript - это настоящий функциональный язык, и все функции (анонимные или нет) действительно полнофункциональные замыкания , поэтому переменные извне функции по-прежнему доступны.

универсальным методом решения «параметров передачи» является построение замыканий во время выполнения:

function makeSuccessFunc (divname) {
    return function (msg) {
        $(divname).removeClass('isequeue_updating'); 
        $(divname).html(msg); 
        $("#somethingfromthemsg").treeview(); 
    };
};

так что вы можете сделать:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
     var divname ="#queuediv"+i; 

    $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      url: "test12.aspx/GetHtmlTest", 
      // data would be populated differently so that each div gets its own result- for now it doesn't matter 
      //data: "{ 'Dividend': '" + $("#Dividend").val() + "' }", 
      data: "{}", 
      // Error! 
      error: function(xhr, status, error) { 
          // Boil the ASP.NET AJAX error down to JSON. 
          //var err = eval("(" + xhr.responseText + ")"); 

          // Display the specific error raised by the server 
          //alert(err.Message); 
          alert("AJAX Error!"); 
      }, 
       success: makeSuccessFunc (divname)
    }); 
} 
});
1 голос
/ 06 апреля 2009

Вы можете обернуть каждую итерацию цикла for в анонимную функцию следующим образом:

$(document).ready(function() { 
for (i= 1;i<=4;i++) 
{ 
(function (){
     var divname ="#queuediv"+i; 

    $.ajax({ 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      url: "test12.aspx/GetHtmlTest", 
      data: "{}", 
      error: function(xhr, status, error) { 
          alert("AJAX Error!"); 
      }, 
       success: function(msg) { 
        $(divname).removeClass('isequeue_updating'); 
        $(divname).html(msg); 
        $("#somethingfromthemsg").treeview(); 
      } 
    });
})(); 
} 
});

Гораздо более простой пример:

<div id="output1"></div><div id="output2"></div><div id="output3"></div><div id="output4"></div><div id="output5"></div>
<script language="javascript">
for(var a=1; a<=5; a++) {
  (function (){
    var divName = "output" + a;
    var b = a;
    setTimeout(function(){document.getElementById(divName).innerHTML = b;}, 2000);
  })();
}
</script>
0 голосов
/ 06 апреля 2009

Нажмите.

Вот пара хороших статей о замыканиях, которые также помогли мне:

JavaScript, время для закрытия

http://devlicio.us/blogs/sergio_pereira/archive/2009/02/23/javascript-time-to-grok-closures.aspx

Закрытия в C #

http://www.lostechies.com/blogs/derickbailey/archive/2009/02/23/closures-in-c-variable-scoping-and-value-types-vs-reference-types.aspx

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