尽管返回了其他数据,但未设置Ajax成功变量

时间:2015-02-05 17:49:10

标签: javascript jquery ajax json jsp

编辑:基本问题是一样的,但是我没有传回一个全局按钮数组,而是传回一个getButtons()函数。

我正在向服务器发出AJAX请求以获取数据以填充弹出框,并将数据作为JSP传回。 JSP的一部分包括一个JSON对象,其中包含客户端用来绘制一些按钮的数据。

问题是有时JSON对象在成功回调上没有准备就绪,因此按钮不会被绘制。 JSP的其余部分就在那里,因此辅助功能可以正常工作。

对于大多数页面来说,这确实可以正常工作,但在某些页面上,内容准备得更快,按钮尚未设置。如何确保设置按钮?

服务器代码:

//Arbitrary JSP code prior to this function

function getButtons() {
    var buttons = [];

    buttons.push(addButton('Send', 'functionName', buttonDescription));        
    buttons.push(addButton('Cancel', 'functionName', buttonDescription));

    return buttons;
}

客户代码:

popupBoxFunction(action, params, global) {
 $.ajax({
    url: action,
    type: 'POST',
    data: params,
    dataType: 'html',
    global: global,
    success: function (data, textStatus, xhr) {

    $("#container").html(data);

    if (typeof getButtons() != "undefined") {
       var myButtons = generatePopupButton(getButtons());
       for (var i = 0; i < myButtons.length; i++) {
           //do something
       }

    }

//arbitrary rest of function
}

3 个答案:

答案 0 :(得分:2)

选项 - 1

如果您希望在所有按钮都可用后调用generatePopupButton,为什么我们不在getButtons内调用它。这样你就不必检查按钮是否可用,一切都是一个接一个地发生。

您的JSP:

<script>
// make it an IIFE so that it's executed right after parsing
(function() {
    var buttons = [];

    buttons.push(addButton('Send', 'functionName', buttonDescription));        
    buttons.push(addButton('Cancel', 'functionName', buttonDescription));

    var myButtons = generatePopupButton(buttons);
      for (var i = 0; i < myButtons.length; i++) {
           //do something
      }
})();
</script>

您的客户代码: -

popupBoxFunction(action, params, global) {
    $.ajax({
       url: action,
       type: 'POST',
       data: params,
       dataType: 'html',
       global: global,
       success: function (data, textStatus, xhr) {
          /* just add your html and script to DOM
           and wait for the browser to execute it for you */
          $("#container").html(data);
       }
    });

   //arbitrary rest of function
}

选项 - 2

如果您不喜欢将generatePopupButton和其他脚本代码移入JSP中,可以使用大多数模板引擎中使用的Function Body As a String技术。

在您的JSP中: -

<!-- make sure type is not text/javascript, something gibberish that 
     is not known to browser -->
  <script id="template" type="my-type">

     var buttons = [];
     buttons.push(addButton('Send', 'functionName', buttonDescription));        
     buttons.push(addButton('Cancel', 'functionName', buttonDescription));
     return buttons;

  </script>

确保script类型不是浏览器已知的类型。如果您愿意,您甚至可以将script代码更改为div代码:)

在您的客户代码中: -

     $.ajax({
           url: action,
           type: 'POST',
           data: params,
           dataType: 'html',
           global: global,
           success: function (data, textStatus, xhr) {
              $("#container").html(data);
              var funBody = $('#template').html();
              /* Now that we've function body as text  
                 retrieve that in code*/
              var fn = new Function(funBody);
              // Now that we've the function invoke it to get buttons
              var myButtons = generatePopupButton(fn());
              for (var i = 0; i < myButtons.length; i++) {
                //do something
              }
           }
        });

这是使用第二种方法的bin

甚至还有其他方法可以做到这一点,但这两个方法只是从我的头脑中开始:)

答案 1 :(得分:1)

根据我的说法,最好的方法是在html语句中移动$("#container").html(html)设置IF的代码,以便只在按钮后呈现html已经确定了。

修改

因为渲染HTML和BUTTON是独立的。在渲染HTML之前,可以引入最小量的延迟,以便渲染HTML和渲染按钮之间的差异减小。

function popupBoxFunction(action, params, global) {
var ajaxPromise = $.ajax({
                  url: action,
                  type: 'POST',
                  data: params,
                  dataType: 'html',
                  global: global
                 });


}

promiseAjax.done(function(html){
setTimeout(function(html) {
           $("#container").html(html);
        }, 300);
if (typeof getButtons() != "undefined") {
   var myButtons = generatePopupButton(getButtons());
   for (var i = 0; i < myButtons.length; i++) {
       //do something
   }
 //  $("#container").html(html);
}
 });

答案 2 :(得分:0)

在检查if (typeof getButtons() != "undefined") {之前,你能不能通过几毫秒。

例如,内部成功处理程序可以尝试类似以下内容:

success: function (data, textStatus, xhr) {
    $("#container").html(data);
    setTimeout(function(){
       if (typeof getButtons() != "undefined") {
         var myButtons = generatePopupButton(getButtons());
         for (var i = 0; i < myButtons.length; i++) {
             //do something
         }// end for loop
       } //end if check
    },500); //500 milli sec delay
}// end success handler 

success: function (data, textStatus, xhr) { $("#container").html(data); setTimeout(function(){ if (typeof getButtons() != "undefined") { var myButtons = generatePopupButton(getButtons()); for (var i = 0; i < myButtons.length; i++) { //do something }// end for loop } //end if check },500); //500 milli sec delay }// end success handler