2

我正在使用基于 jQuery 的select2替换组合框,并且我必须定义一个回调来处理我从 json rest web 服务接收到的数据。

问题是,在同一个回调中,我必须发出另一个 GET 请求来获取匹配记录的总数,以便 select2 可以决定是否必须加载更多结果(它具有无限滚动功能)

代码是这样的:

$("#country").select2({
  ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
    url: 'http://localhost:9000/api/countries',
    dataType: 'json',
    data: function(term, page) {
      return {
        filter: term,
        page: page,
        len: 10
      };
    },
    results: function(data, page) {
      return {
        results: data, more: ????
      };
    }
  }
});

问题是我不知道如何发出异步请求(我正在发出跨域请求,并且文档说在这种情况下不支持异步)并等待它完成,然后再从结果回调中返回。

select2 页面中的示例如下所示:

results: function (data, page) {
  var more = (page * 10) < data.total; // whether or not there are more results available
  // notice we return the value of more so Select2 knows if more results can be loaded
  return {results: data.movies, more: more};
}

问题是我的 Web 服务返回来自不同端点的记录总数,所以我必须发出另一个请求,如下所示:http://localhost:9000/api/countries?filter=term

任何的想法?

4

3 回答 3

8

您不能等待 javascript 中的异步回调。您必须根据来自实际回调的异步响应来重组代码以完成所有未来的工作。

如果您需要进行多个连续的 ajax 调用,那么您发出第一个,然后在第一个 ajax 调用的成功处理程序或响应处理程序中,发出第二个 ajax 调用,并在第二个的响应处理程序中执行任何操作你想处理数据。

如果看到您正在使用该.select2()框架。在框架中,结果回调是 ajax 调用返回的地方。在该函数中,您将使用普通的 jQuery ajax 调用发出第二个 ajax 调用,并在第二个 ajax 调用的成功处理程序中,您将对返回的最终数据执行任何您想要执行的操作。您将无法使用结果回调的正常返回值,因为您在需要返回的点上还没有最终数据。我认为这只是一个限制.select2(),因为它只支持单个 ajax 调用。这只是意味着您不能使用一点内置行为,而必须自己使用自己的代码应用结果,但它没有.select2()

看起来您可能只想change直接挂钩事件而不使用它们的内置 ajax 东西,因为如果您需要两个序列化的 ajax 调用,它看起来并不能真正为您提供很多东西。

于 2012-08-28T04:00:31.607 回答
4

我研究了select2上的源代码,最后得出了这个解决方案

var ajax = {
  url: 'http://localhost:9000/api/countries',
  len: 3,
};

$("#country").select2({
  query: function(options) {
    var data = {
      filter: options.term,
      page: options.page,
      len: ajax.len
    };
    $.ajax({
      url: ajax.url,
      data: data,
      dataType: 'json',
      type: 'GET',
      success: function(data) {
        $.ajax({
          url: ajax.url + '/count',
          data: { filter: options.term },
          dataype: 'json',
          success: function(resp) {
            var total = parseInt(resp, 10);
            var more = (options.page * ajax.len) < total;
            options.callback({results: data, more: more});
          }
        });
      }
    });
  },
});

如您所见,当第一次获取(ajax.url)完成时,我发出另一个请求(ajax.url + '/count'),只有当第二个请求完成时,我才调用 options.callback,有效地序列化两个 ajax 调用......

事实上,来自 select2 的 ajax 函数具有更多功能,例如节流和丢弃乱序响应,我也只是移植了它们,但为了不使示例复杂化,我将它们排除在此响应之外......

于 2012-08-28T07:53:21.163 回答
0

除了jfriend00的回答(这很好,顺便说一句),我发现了followgin解决方法,它基本上是同步发出请求,尽管jquery docs它似乎工作(至少对于chromium 18.0和jquery 1.8.0)

我只是发布它以防有人发现它有用...

var config = {
  url: 'http://localhost:9000/api/countries',
  len: 20,
  term: ''
}
$("#country").select2({
  ajax: { 
    url: config.url,
    dataType: 'json',
    data: function(term, page) {
      config.term = term;
      return {
        filter: term,
        page: page,
        len: config.len
      };
    },
    results: function(data, page) { // parse the results into the format expected by Select2.
      var more = false;
      $.ajax({
        url: config.url + '/count',
        data: { filter: config.term },
        cache: false,
        async: false,
        success: function(resp) {
          var total = parseInt(resp, 10);
          more = (page * config.len) < total;
        },
        async:false
      });
      return {
        results: data, more: more
      };
    }
  }
});
于 2012-08-28T04:32:13.560 回答