如何 watch/listen 到变量并触发 "onChange" 事件(模块化 JS)

How to watch/listen to a variable and trigger an "onChange" event (Modular JS)

我想听this.progress变量。 每当它发生变化时——它应该更新我的图表加载百分比和进度条加载百分比。

我尝试在我的 bindEvents() 部分使用 .change,但我收到一条错误消息,指出对变量应用 .change 函数无效(仅适用于元素)。

所以我尝试做类似 this 的事情(参见 cacheDom 下的最后一个变量):

(function() {

    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');
            this.progress       = function(){

                var progressPrecent = 0;

                return {

                    getProgress: function () {
                      return progressPrecent;
                    },
                    updateValue: function(progressPrecent) {
                        this.updateProgressTableChart(progressPrecent);
                    }
                }

            };
        },
        // Bind click events (or any events..)
        bindEvents: function() {

            var that = this;

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

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

            // On Change inputs
            /*this.progress.change(function(){

                // Show Chart Loading 
                that.qwChart.showLoading({ 
                    text: that.returnNumWithPrecent(that.progress)
                });
                that.setProgressBarValue(that.progress);

            });*/
        },
        // Get data, prevent submit defaults and submit. 
        sendData: function(sdate, edate, e) {
            e.preventDefault();
            let that = this;

            $.ajax({
                type: 'POST',
                url: "/potato/ajax.php?module=potato_module",
                dataType: 'json',
                data: {
                        start_ts: sdate,
                        stop_ts: edate, 
                        submitted: true
                },
                beforeSend: function() {

                    console.log(that.progress);

                    setTimeout(function (){

                      // Something you want delayed.

                    }, 1000);
                                    that.progress       = 50;

                    setTimeout(function (){

                      // Something you want delayed.

                    }, 2000);
                                    that.progress       = 60;


                    // that.setProgressBarValue(that.progress);

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

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

            that.dataDisplayed = true;
        }, 
        ...........
        ......................
        ...................................
        ...............................................
})();

console.log(this.progress) 所在的控制台中不断出现此错误:

undefined

您可以将 defineProperty 与您自己的 setter 一起使用。

    (function() {

    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.updateProgressTableChart(value);
                      this.progressPrecent = value;
                    }

                }
            });
        },
        // Bind click events (or any events..)
        bindEvents: function() {

            var that = this;

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

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

            // On Change inputs
            /*this.progress.change(function(){

                // Show Chart Loading 
                that.qwChart.showLoading({ 
                    text: that.returnNumWithPrecent(that.progress)
                });
                that.setProgressBarValue(that.progress);

            });*/
        },
        // Get data, prevent submit defaults and submit. 
        sendData: function(sdate, edate, e) {
            e.preventDefault();
            let that = this;

            $.ajax({
                type: 'POST',
                url: "/potato/ajax.php?module=potato_module",
                dataType: 'json',
                data: {
                        start_ts: sdate,
                        stop_ts: edate, 
                        submitted: true
                },
                beforeSend: function() {

                    console.log(that.progress);

                    setTimeout(function (){

                      // Something you want delayed.

                    }, 1000);
                                    that.progress       = 50;

                    setTimeout(function (){

                      // Something you want delayed.

                    }, 2000);
                                    that.progress       = 60;


                    // that.setProgressBarValue(that.progress);

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

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

            that.dataDisplayed = true;
        }, 
        ...........
        ......................
        ...................................
        ...............................................
})();