jQuery.ajax called twice from userValuesChanged in dateRangeSlider

房东的猫 提交于 2019-12-25 02:38:39

问题


I am using jQDateRangeSlider to trigger a jQuery.ajax call.There are two ways in which the slider can be moved.

  1. By moving the ends of the slider individually
  2. By moving the entire highlighted block from one place to other

In case of 1, my code works fine, but in case 2, the 'userValuesChanged' gets invoked two or four times.Is this some bug with the widget or am I doing something wrong here? This is how my code looks?

function init() {
    var tp = $('tp').value;
    if (tp == 'Daily') {
        dataFile1 = "http://localhost:8080/composite2/Composite/datejson";

        d3.json(dataFile1, function (error, data) {
            if (data) dataset1 = data;
            var min = dataset1[0].a;
            var jugad = dataset1[0].c;
            jugad2 = new Date(jugad);
            var min2 = new Date(min);
            var max = dataset1[dataset1.length - 1].b;
            var max2 = new Date(max);

            function addZero(val) {
                if (val < 10) {
                    return "0" + val;
                }
                return val;
            }
            var s = $j("#slider").dateRangeSlider({

                bounds: {
                    "min": min2,
                    "max": max2
                },
                range: {
                    min: {
                        hours: 25
                    },
                    max: {
                        days: 7
                    },
                },
                formatter: function (val) {
                    var m = moment(val);
                    return m.format("DD/MM/YYYY HH:00:00 ");
                },
                defaultValues: {
                    min: min2,
                    max: max2
                }
            });
            x = jugad2;
            x.setMinutes(0);
            x.setSeconds(0);
            z = x.getFullYear() + '-' + (x.getMonth() + 1) + '-' + x.getDate() + ' ' + x.getHours() + ':' + '00' + ':' + '00';
            var y = (s.dateRangeSlider("values").max);
            y.setMinutes(0);
            y.setSeconds(0);
            b = y.getFullYear() + '-' + (y.getMonth() + 1) + '-' + y.getDate() + ' ' + y.getHours() + ':' + '00' + ':' + '00'
            jQuery.ajax({
                type: 'POST',
                data: 'metric=' + $('metric').value + '&tp=' + $('tp').value + '&date_hour=' + z + '&date_hour=' + b,
                url: '/composite2/Composite/ajaxGetMv',
                success: function (data, textStatus) {
                    loadData(data);
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {}
            });

            $j('#slider').on("userValuesChanged", function (e, data) {
                var x = data.values.min;
                x.setMinutes(0);
                x.setSeconds(0);
                z = x.getFullYear() + '-' + (x.getMonth() + 1) + '-' + x.getDate() + ' ' + x.getHours() + ':' + '00' + ':' + '00';
                var last = data.values.max;
                last.setMinutes(0);
                last.setSeconds(0);
                b = last.getFullYear() + '-' + (last.getMonth() + 1) + '-' + last.getDate() + ' ' + last.getHours() + ':' + '00' + ':' + '00';
                jQuery.ajax({
                    type: 'POST',
                    data: 'metric=' + $('metric').value + '&tp=' + $('tp').value + '&date_hour=' + z + '&date_hour=' + b,
                    url: '/composite2/Composite/ajaxGetMv',
                    success: function (data, textStatus) {
                        loadData(data);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {}
                });
            })
        });
    } //end of Daily Slider
} //end of init()

UPDATE

init() is being called from function decide.

function decide()
{
var tp = $('tp').value;
if (tp == 'Daily')
{

  init();
}
 else
 {

  init1();
 }
}

This function decide() is being called on the onchange of a dropdown 'tp'


回答1:


I'm having to guess a bit here as you don't say what versions of the libraries you're using. However I tested the plugin in jsFiddle and it works fine, so I assume that you're doing repeated calls to init which are binding extra handlers to the event. You say:

This function decide() is being called on the onchange of a dropdown tp

This means that whenever that dropdown changes init is called again and the handler is added again to that event. You can see this happening here in my jsFiddle, counts are normal until you click the button to call init() again. There are a few ways round this, see the comments in the fiddle as well.

Option 1 -- Simple but not really elegant.

Just destroy the slider at the start of the init() routine:

function init() {      
    $j("#slider").dateRangeSlider("destroy");

This doesn't throw an error if the slider hasn't been initialized (looks like the plugin has some sanity checking) but it may cause a visual glitch on some browsers.

Option 2 -- A bit better

Use a global variable to keep a note of if you've created the event

var is_init = false;
function init() { 

    // ... other code ... 

    if (!is_init) 
    {
        $j('#slider').on("userValuesChanged", function (e, data) {
            // ... handler code ... 
        });
        is_init = true;
    } 
}

There are a few other ways to use the 'global variable' idea, including faking static function variables but this is the simple way and it may work since you have two init routines.

Option 3 -- Probably my choice

Your init() function is really a (re)init since it can be called more than once. You only want to bind the handler once so you can just do it outside the init function (or inside a different function that's only called once). You can do this before calling init, just after page load. This works it just registers an event handler, it doesn't care that at that point that element can't generate the event, it'll handle it just fine later. Here's a fiddle for that.

It really sounds like you want an init function somewhere that's called once (not tied to an element) and a reinit function tied to the dropdown that just changes the values but doesn't rebind the event. I don't see anything in your event handler that changes depending on the different settings but if there is you'll probably have to go with Option 1.

There are some other options (unbind the event handler, detect if there's already a handler bound) but they may run into more trouble if other handlers are also bound to that event.

And this may not be the root cause of your problem, but I hope the fiddles help you in any case.



来源:https://stackoverflow.com/questions/25759135/jquery-ajax-called-twice-from-uservalueschanged-in-daterangeslider

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