weixin_33716941 2016-07-28 12:11 采纳率: 0%
浏览 60

执行命令行为

I'm writing a function that upon call should populate the page with tiles. Data on tiles are acquired from the remote DB (hence the AJAX request). I'm also using jQuery 3.0 in the code.

Here is the function:

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;
        }
    });
}

I don't think the HTML where this is getting injected is relevat as that part is working fine.

The problem is that the fadeout and both each loops that get called upon success, get callout out of order. I tried to log the time at which each get executed and this is what I get:

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

I'm displaying 6 tiles, so comments 2 and 3 should fire 6 times and 1 only once.

  • Why doesn't 1 execute first?

  • Why is 1 executed 6 times? EDIT: Figured that one myself just now.

  • If 1 is executed last, why doesn't it delete all the tiles created before?

Another problem is that the first time it displays 6 tiles, but second (and onwards), it only displays 5 tiles (first is missing).

Anyone can help me explain what is going on and how can I avoid such bahaviour?

Thank you.

  • 写回答

2条回答 默认 最新

  • weixin_33720078 2016-07-28 12:59
    关注

    I see multiple issues with your code so here is what I can recommend:


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

    should just be

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

    because jQuery's AJAX function will convert it for you.


    Try console.log(data.TileData);; if you are already receiving a JS object/array then there is ZERO reason to call var json = $.parseJSON(data.TileData); so you should remove that.


    Instead of

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

    use

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

    Now for the final issue, fadeOut() and fadeIn() getting called out of order.

    Try this:

    // 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())
        });
    });
    
    评论

报告相同问题?