2016-07-28 185 views
1

我正在写一个函数,在调用时应该用瓦片填充页面。瓦片数据是从远程数据库中获取的(因此是AJAX请求)。我也在代码中使用jQuery 3.0。执行命令bahaviour

下面是函数:

function populateDashboard() { 
    var tileBlueprint = '<div class="dashboard_tile">\ 
        <div class="dashboard_tile_content">\ 
         <table class="tile_table">\ 
          <tr class="tile_title">\ 
           <td>$title</td>\ 
          </tr>\ 
          <tr class="tile_data">\ 
           <td>$value</td>\ 
          </tr>\ 
         </table>\ 
        </div>\ 
       </div>'; 

$.ajax({ 
     url: 'http://' + AppVar.ServerUrl + '/restapi/Dashboard_GetData', 
     type: 'POST', 
     data: JSON.stringify({ 
      'SessionId': AppVar.SessionId 
     }), 
     dataType: 'json', 
     contentType: "application/json", 
     success: function (data) { 
      if (data.ResultCode === '0') { 
       //current tiles get wiped 
       $('.dashboard_tile').fadeOut(100, function() { 
        $(".tile_handler").empty(); 
        console.log("1 - " + Date.now()) 
       }); 

       //new tiles are parsed and data is injected into the string which represents the tile 
       //tiles are saved into an array 
       var json = $.parseJSON(data.TileData); 
       var tileArr = []; 
       $.each(json.tiles, function (index, element) { 
        tile = tileBlueprint.replace("$title", $.i18n("dashboard-" + element.title)); 
        tile = tile.replace("$value", element.value); 
        tileArr[index] = tile; 
        console.log("2 - " + Date.now()) 
       }); 

       //now I loop trough the previously created array to populate the page 
       $.each(tileArr, function (index, element) { 
        setTimeout(function() { 
         $(element).hide().appendTo(".tile_handler").fadeIn(1000); 
        }, 1000 * index); //delay made longer to see the effect better 
        console.log("3 - " + Date.now()) 
       }); 
      } else { 
       ons.notification.alert($.i18n('error-retriving_data_problem')); 
       return; 
      } 
     }, 
     error: function (request, error) { 
      ons.notification.alert($.i18n('error-conn_error')); 
      return; 
     } 
    }); 
} 

我不认为这个地方是越来越注入HTML是relevat作为部分工作正常。

的问题是,淡出两者每个循环,即获得在成功叫,得到标注出故障了。我试图在记录每个得到执行的时间,这就是我得到:

//first run 
2 - 1469707068268 (6 times) 
3 - 1469707068269 (6 times) 
//second run 
2 - 1469707181179 (2 times) 
2 - 1469707181180 (3 times) 
2 - 1469707181181 
3 - 1469707181181 
3 - 1469707181182 (4 times) 
3 - 1469707181183 
1 - 1469707181283 
1 - 1469707181284 (2 times) 
1 - 1469707181285 (2 times) 
1 - 1469707181286 

我显示6瓦,所以评论和应该解雇6次,只有1 一旦。

  • 为什么不执行第一?

  • 为什么执行了6次?编辑:只是我自己现在。

  • 如果最后执行,它为什么不删除以前创建的所有瓷砖?

另一个问题是,它第一次显示6个瓷砖,但第二个(和以后),它只显示5个瓷砖(第一个缺失)。

任何人都可以帮助我解释发生了什么,我该如何避免这种行为?

谢谢。

回答

3

为什么不执行第一,为什么执行6倍?

.fadeOut的文档中,第二个参数是“动画完成后调用的函数,每个匹配元素调用一次”。

所以在这种情况下,函数将在〜100ms(作为第一个参数提供的延迟)之后调用,并且将被调用六次(每个匹配元素一次)。

如果最后执行,它为什么不删除以前创建的所有瓷砖?

如上所见,在100ms后运行。然而,实际的节点后1000 * index女士补充说:

setTimeout(function() { 
    $(element).hide().appendTo(".tile_handler").fadeIn(1000); 
}, 1000 * index); 

所以对于所有,但代码实际上追加该节点的第一个节点后运行。但是,对于第一个节点(注意:索引0 => 1000 * 0 = 0ms延迟),appendTo代码会直接运行,这意味着在100ms后调用.empty()时它将被删除,这意味着您将只会参见6个节点中的5个。

解决这些问题的方法是以某种方式“同步”代码,使其以您期望的方式运行。这通常是回调函数的用途,您可以在完成某些回调函数后将要运行的代码放入回调函数中。在这种情况下,一个解决办法可以是移动的“并称”代码到淡出回调:中.promise.done

$('.dashboard_tile').fadeOut(100).promise().done(function() { 
    $(".tile_handler").empty(); 
    var json = $.parseJSON(data.TileData); 
    var tileArr = []; 
    $.each(json.tiles, function (index, element) { 
     tile = tileBlueprint.replace("$title", $.i18n("dashboard-" + element.title)); 
     tile = tile.replace("$value", element.value); 
     tileArr[index] = tile; 
    }); 
    // ... 
}); 

注意使用,这给了我们一个回调,一旦所有的元素完成动画,而不是为每个元件。

1

我看到多个问题与你的代码,所以这里是我可以推荐:


data: JSON.stringify({ 
    'SessionId': AppVar.SessionId 
}), 

应该只是

data: {'SessionId': AppVar.SessionId}, 

因为jQuery的AJAX功能将其转换为您服务。


尝试console.log(data.TileData);;如果你已经收到一个JS对象/数组,那么ZERO的原因就是调用var json = $.parseJSON(data.TileData);,所以你应该删除它。


而不是

$.each(json.tiles, function (index, element) {` 

使用

$.each(data.TileData.tiles, function (index, element) { 

现在对于最后一个问题,​​和fadeIn()得到所谓的乱序。

试试这个:

// Make sure the fadeOut() finishes before calling more stuff!!! 

//current tiles get wiped 
$('.dashboard_tile').fadeOut(100, function() { 
    $(".tile_handler").empty(); 
    console.log("1 - " + Date.now()) 

    //new tiles are parsed and data is injected into the string which represents the tile 
    //tiles are saved into an array 
    var tileArr = []; 
    $.each(data.TileData.tiles, function (index, element) { 
     tile = tileBlueprint.replace("$title", $.i18n("dashboard-" + element.title)); 
     tile = tile.replace("$value", element.value); 
     tileArr[index] = tile; 
     console.log("2 - " + Date.now()) 
    }); 

    //now I loop trough the previously created array to populate the page 
    $.each(tileArr, function (index, element) { 
     setTimeout(function() { 
      $(element).hide().appendTo(".tile_handler").fadeIn(1000); 
     }, 1000 * index); //delay made longer to see the effect better 
     console.log("3 - " + Date.now()) 
    }); 
}); 
+0

我试过不使用'JSON.stringify',但后来我的.NET后端没有收到数据。对于'$ .each(data.TileData.tiles,function(index,element){',这里的代码根本没有任何反应,不知道我的后端是不是奇怪的或者什么的。“ – rancor1223

+0

对不起,你是正确的'$ .each(data.TileData.tiles,function(index,element){'。它不工作,因为我只是从后端解析一个JSON字符串作为占位符输出。现在我的后端是发送适当的JSON,你的解决方案是正确的。 – rancor1223

+0

@ rancor1223很高兴我能帮忙! – MonkeyZeus