2016-07-28 190 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