.hasClass on.click没有注册函数调用,直到第二个.click..ajax异步?

时间:2014-06-15 18:17:33

标签: javascript jquery ajax twitter-bootstrap promise

某些复选框按钮(使用引导程序)会触发ajax get call on.click,并且选中按钮的活动性会提供过滤机制。

现在,为什么过滤只能在第二次单击事件上单击正确(如果单击btn1,则ajax运行,使用/.one.two.three ...并且仅在随后单击btn2时才会执行它注册为/.two.three ..并且只有当btn3随后被点击时才注册为/.three ..?http://jsfiddle.net/ENJH9/2/

或者,如果在调用refreshData()之前删除了on.click类,则数据会正确提供,但视图不会反映removeClass!? http://jsfiddle.net/ENJH9/3/

所有按钮都以活动类(http://getbootstrap.com/javascript/#buttons)开头:

<div class="btn-group" data-toggle="buttons" id="theBtns">
  <label class="btn btn1 active">
    <input type="checkbox">one
  </label>
  <label class="btn btn2 active">
    <input type="checkbox">two
  </label>
  <label class="btn btn3 active">
    <input type="checkbox">three
  </label>
  <label class="btn btn4 active">
    <input type="checkbox">four
  </label>
</div>

这里是每个按钮的.click事件之后的.get调用:

function refreshData() {

    console.log('started refreshData()')

    URL = '';

    var filtering = function() {

        if($(".btn1").hasClass("active")) { URL += ".one"; }
        if($(".btn2").hasClass("active")) { URL += ".two"; }
        ...

    console.log('done filtering: ' + URL);

        return URL;
    };

    $.when( filtering() ).done(function() {

    console.log('now data refresh with %s filtering', URL)

    $.ajax({
      url:"http://localhost:4200/api/v1/data" + URL,
      method:'get',
      success: foundAllSuccess,
      error: foundError

    })

    });

}

这里的clickCal注释掉了click事件(按钮仍然保持在视觉上活动状态,并且该类仍然保留在检查器中,但服务器使用此设置准确过滤):

$( ".btn1" ).click(function() {
  // if($(".btn1").hasClass("active")) {$(".btn1").removeClass("active"); console.log('hide btn1 data');}
  // else {$(".btn1").addClass("active"); console.log('btn1 data active');}
  refreshData();
}); // .btn1.click

1 个答案:

答案 0 :(得分:1)

首先,你遇到问题的主要原因是bootstrap和jQuery不能太舒服地坐在一起 - 至少在这种情况下不是这样。 jQuery的点击事件如此早地发送,它发生在bootstrap切换为“活动”之前。因此refreshData()在点击之前按下按钮状态,而不是在点击之后。这可以用timeout()来解决,以延迟refreshData()的执行,直到bootstrap完成它之后。

其次,您不需要切换active作为引导程序来查看该方面。

第三,通过更好地利用jQuery,可以更有效地编写代码。

function refreshData(e) {
    var URL = $(e.target).closest(".btn-group").find("label").map(function (i) {
        if ($(this).hasClass("active")) {
            return ['.one', '.two', '.three', '.four'][i];
        } else {
            return null;
        }
    }).get().join(''); //.map() returns an array, .join() concatenates the strings in the array into a single string.

    alert('now ajax call with filtering :' + URL);
}

$("#theBtns .btn").on('click', function (e) {
    setTimeout(function () {
        refreshData(e);
    }, 0);
}); 

<强> DEMO

请注意,即使延迟为零也足以达到我们的目的,因为从setTimeout执行的代码将在当前线程运行完成后尽早在单独的事件线程中运行。

可能会有更多的&#34; bootstrapy&#34;实现同样目的的方法,但我不打算通过大量的bootstrap文档来查找。