How to run a progress bar (that gets % increments every x seconds) in parallel to an ajax call?

僤鯓⒐⒋嵵緔 提交于 2019-12-11 16:33:51

问题


This is part of my object:

const qwData = {

    // Initialize functions
    init: function() {
        this.cacheDom();
        this.bindEvents();
    },
    // Cache vars 
    cacheDom: function() {
        this.dataDisplayed  = false;
        this.countUsers     = <?php echo $_SESSION['all_users_count_real']; ?>;
        this.$form          = $('#frm_reportit');
        this.start_date     = this.$form[0][9].value;
        this.end_date       = this.$form[0][10].value;
        this.dateCount      = this.countDays(this.start_date, this.end_date);
        this.show           = document.querySelector('#btn-show');
        this.downloadBtn    = document.querySelector('#download_summary_button');
        this.$dataContainer = $('#qw-data-container');
        this.$qwTable       = $('#qwtable');
        this.$qwTbody       = this.$qwTable.find('tbody');
        this.qwChart        = echarts.init(document.getElementById('main-chart'));
        this.progressBar    = document.querySelector('.progress-bar');
        Object.defineProperty(this, "progress", {
            get: () => {
               return this.progressPrecent || 0;
            },
            set: (value) => {

                if(value != this.progressPrecent){
                  this.setProgressBarValue(value);
                  this.qwChartProgress = this.returnNumWithPrecent(value);
                }
            }
        });
        this.qwChartProgress= this.progress;
    },
    // Bind click events (or any events..)
    bindEvents: function() {

        var that = this;

        // On click "Show" BTN
        this.show.onclick = this.sendData.bind(this);

        // On Change inputs
        this.$form.change(function(){
            that.updateDatesInputs(this);
        });

    },

sendData: function(e) {
    e.preventDefault();
    let that = this;

    $.ajax({
        type: 'POST',
        url: "/test/ajax.php?module=test_module",
        dataType: 'json',
        data: {
                start_ts: that.start_date,
                stop_ts: that.end_date, 
                submitted: true
        },
        beforeSend: function() {

            // Show Chart Loading 
            that.qwChart.showLoading({ 
                color: '#00b0f0', 
                // text: that.returnNumWithPrecent(that.progress)
                text: that.qwChartProgress
            });

            // If data div isn't displayed
            if (!that.dataDisplayed) {
                // Show divs loading
                that.showMainDiv();
            } else {
                that.$qwTbody.slideUp('fast');
                that.$qwTbody.html('');
            }
        },
        complete: function(){


            let timer = setInterval(that.incrementProgress, 500);

        },
        success: function(result){

            // Set progressbar to 100%
            that.setProgressBarTo100();

            // Show Download Button
            that.downloadBtn.style.display = 'inline-block';

            // Insert Chart Data
            that.insertChartData(result);

            // Insert Table Data
            that.insertTableData(result);
        }
    });

    that.dataDisplayed = true;
},
// Insert Data to Table
incrementProgress: function(){
    this.progress += 10;
},
..... 
.............
....................

I am trying to get this.progress to get incremented every 0.5 seconds by 10% (by adding 10 to this.progress). I'm not sure where to do that, and how. I tried adding it to beforeSend: and complete: but all i get is a 0% progress bar without any time delays. How is the proper way to write this?


回答1:


Object.defineProperty(this, "progress", {
            get: () => {
               return this.progressPrecent || 0;
            },
            set: (value) => {

                if(value != this.progressPrecent){
                  this.progressPrecent = value;
                  this.setProgressBarValue(value);
                  this.qwChartProgress = this.returnNumWithPrecent(value);
                }
            }
        });

This was the problem this.progressPrecent = value;

It was always 0 because when getting the value it didn't set it in this.progressPrecent.




回答2:


You still have the same problem. Here is the digest of it:

My test definition:

var test = {
    progress: 0,
    increment:function(){
        this.progress = this.progress+10;
    }
}

test is { progress: 0, increment: function }

test.progress();

test is { progress: 10, increment: function }

setTimeout(test.increment, 20)

test is { progress: 10, increment: function } since method is passed by reference!!!

setTimeout( function(){test.increment() }, 20)

test is { progress: 20, increment: function } since the context is preserved!!!

So, even if your timer is correctly started, it will increment progress in whatever context, which is not the intended one.



来源:https://stackoverflow.com/questions/50347952/how-to-run-a-progress-bar-that-gets-increments-every-x-seconds-in-parallel-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!