2016-07-28 21 views
1

私はコール時にタイルでページを埋めるべき関数を書いています。タイルに関するデータは、リモートDBから取得されます(したがって、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枚のタイルを表示しています一度。

  • はなぜは、最初に実行しないのですか?

  • なぜが6回実行されるのですか?編集:私はちょうど今自分自身を考え出しました。

  • が最後に実行されると、以前に作成されたタイルはすべて削除されないのはなぜですか?

もう1つの問題は、最初に6つのタイルを表示するが、2番目(以降)、5つのタイルしか表示しないことです(最初は欠落しています)。

誰でも私が何が起こっているのか、どのようにそのような大騒ぎを避けることができますか?

ありがとうございます。

答えて

3

を?

.fadeOutのドキュメントから、2番目のパラメータは、「一致した要素につき1回呼び出されたアニメーションが完了すると呼び出す関数」です。

この場合、関数は〜100ms(最初のパラメータとして指定した遅延)の後に呼び出され、6回(一致する要素ごとに1回)呼び出されます。

が最後に実行されると、以前に作成されたタイルはすべて削除されないのはなぜですか?

上記のように、は100ms後に実行されます。すべてのため

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

だからのが、コードが実際にノードを追加する最初のノードは、後に実行されている:しかし、実際のノードは1000 * indexミリ秒後に添加されます。しかし、最初のノード(注:0 => 1000 * 0 = 0msのインデックスのインデックス)では、appendToコードは直接実行されます。つまり、.empty()が100ms後に呼び出されたときに実際に削除されます。 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つのアニメーション一度すべての要素が終了した単一のコールバックを提供します。この場合、1つの解決策は、フェードアウトのコールバックの中に「追加」コードを移動することができ素子。

1

私はここにあなたのコードで複数の問題を参照してください、私はお勧めできるものです。


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

jQueryのAJAX機能があなたのためにそれを変換しますので、ちょうど

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

でなければなりません。


Try console.log(data.TileData);; JSオブジェクト/配列を既に受け取っている場合は、var json = $.parseJSON(data.TileData);にコールする理由はありませんので、削除する必要があります。


代わりの最後の問題、​​とfadeIn()順不同で呼ば取得のための今

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

使用

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

このお試しください:なぜが最初に実行しないと、なぜは6回実行される

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