具有AJAX源的Bootstrap Typeahead:未按预期返回数组 [英] Bootstrap Typeahead with AJAX source: not returning array as expected

查看:92
本文介绍了具有AJAX源的Bootstrap Typeahead:未按预期返回数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难提前输入引导程序以使其与AJAX源一起正常工作.

I am having a lot of trouble getting bootstraps typeahead to work properly with an AJAX source.

如果我警告要返回的数组,即使我对其进行硬编码以对其进行测试,也可以很好地解决问题.在您输入接近匹配项时,它似乎大部分时间不返回任何内容,或者仅返回数组中的一些内容.

If I alert out the array that is being returned it is perfectly fine, even when I hard code it to test it. It seems to return nothing most of the time or only a few items from the array when you have typed in a near match.

这是我目前的状态:

$('#companyNameInput').typeahead({
      source: function(query, process){

          $.ajax({
            url: ROOT+'Record/checkCompanyName',
            async: false,
            data: 'q='+query,
            type: 'POST',
            cache: false,
            success: function(data)
            {
              companiesFinal = [];
              map = {};
              companies = $.parseJSON(data);
              $.each(companies, function(i, v){
                map[v.name] = v.id;
                companiesFinal.push(v.name);
              })
            }
          })
          process(companiesFinal);

          // return ['test1', 'test2'] This works fine
          return companiesFinal;
      }

有人知道为什么它能正常工作吗?

Does anyone have an idea why this is working properly?

这是我的PHP脚本返回的对象数组的示例. ID为1和1216的对象将显示在预输入下拉列表中,但其他对象中没有.我看不到任何模式或线索,为什么只显示这些模式而不显示其他模式.

Here is an example of the object array returned from my PHP script. Objects with IDs 1 and 1216 show up on the typeahead dropdown, but non of the others do. I can not see any patterns or clue as to why only these would show and not the others.

[
   {
      "id": "1265",
      "score": "40",
      "name": "LMV AB"
   },
   {
      "id": "10834",
      "score": "33",
      "name": "Letona"
   },
   {
      "id": "19401",
      "score": "33",
      "name": "Lewmar"
   },
   {
      "id": "7158",
      "score": "33",
      "name": "Lazersan"
   },
   {
      "id": "3364",
      "score": "33",
      "name": "Linpac"
   },
   {
      "id": "1216",
      "score": "33",
      "name": "L H Evans Limted"
   },
   {
      "id": "1",
      "score": "33",
      "name": "LH Evans Ltd"
   },
   {
      "id": "7157",
      "score": "33",
      "name": "Lazersan"
   }
]

最后是process(companiesFinal)中过去的数组:

["LMV AB", "Letona", "Lewmar", "Lazersan", "Linpac", "L H Evans Limted", "LH Evans Ltd", "Lazersan"]


有人知道吗?我仍然对为什么它仍然不起作用一无所知:(


Anyone have any clue? I am still totally clueless as to why this isn't working still :(

$('#companyNameInput').typeahead({
      source: function(query, process){

        companyTOut = setTimeout(function(){
          return $.ajax({
            url: ROOT+'Record/checkCompanyName',
            data: 'q='+query,
            type: 'POST',
            dataType: 'json',
            cache: false,
            success: function(data)
            {
              var count = 0;
              var companiesFinal = [];
              map = [];
              $.each(data, function(i, v){
                map[v.name] = [v.id, v.score];
                companiesFinal.push(v.name);
              })
              process(companiesFinal);

            }
          })
        }, 250)
      },
      minLength: 2,
      highlighter: function(item)
      {
        $('#companyNameInput').closest('.control-group').removeClass('success')
        companyLocked = false;
        return '<span class="unselectable" title="'+map[item].score+'">'+item+'</span>';
      },
      updater: function(item)
      {
        selectedEntityId = map[item][0];
        selectedCountryScore = map[item][1];
        lockCompany(selectedEntityId);
        return item;
      }
    });


$output .= '['.$output;
    foreach($results as $result) {
      $output .= '{"id":"'.$result['id'].'",';
      $output .= '"score":"'.$result['score'].'",';
      $output .= '"name":'.json_encode($result['name']).'},';
    }
    header('Content-Type: application/json');
    echo substr($output, 0, strlen($output)-1).']';


控制台输出"parm":


Console output for "parm":

[Object, Object, Object, Object, Object, Object]
0: Object
id: "25024"
name: "part"
score: "75"
__proto__: Object
1: Object
id: "15693"
name: "pari"
score: "75"
__proto__: Object
2: Object
id: "28079"
name: "Pato"
score: "50"
__proto__: Object
3: Object
id: "18001"
name: "PASS"
score: "50"
__proto__: Object
4: Object
id: "15095"
name: "PSR"
score: "33"
__proto__: Object
5: Object
id: "22662"
name: "PRP"
score: "33"
__proto__: Object
length: 6
__proto__: Array[0]

推荐答案

更新2

啊,您的服务返回的内容实际上与查询parm不匹配.您的预输入查询是'parm',该查询的返回结果均不匹配.您可以覆盖typeahead插件使用的matcher函数,请参见文档 .只需将其实现为return true即可匹配您的服务返回的所有结果.

Update 2

Ah, your service returns items that actually don't match the query parm. Your typeahead query is 'parm', with which none of the returned results match. You can override the matcher function used by the typeahead plugin, see the docs. Simply implement it as return true to match all results returned by your service.

这是一个更新的版本,它将名称映射到一个ID,以后可以使用. jsfiddle可用.

This is an updated version, that maps the name to an id, which can be used later. A jsfiddle is available.

var nameIdMap = {};

$('#lookup').typeahead({
    source: function (query, process) {
        return $.ajax({
            dataType: "json",
            url: lookupUrl,
            data: getAjaxRequestData(),
            type: 'POST',
            success: function (json) {
                process(getOptionsFromJson(json));
            }
        });
    },
    minLength: 1,
    updater: function (item) {
        console.log('selected id'+nameIdMap[item]);
        return item;
    }
});

function getOptionsFromJson(json) {
    $.each(json, function (i, v) {
        nameIdMap[v.name] = v.id;
    });

    return $.map(json, function (n, i) {
        return n.name;
    });
}

原始答案

您需要进行异步调用,并从成功回调中调用process回调,如下所示:

Original answer

You need to make the call async and call the process callback from within the success callback like this:

$('#companyNameInput').typeahead({
    source: function (query, process) {
        $.ajax({
            url: ROOT + 'Record/checkCompanyName',
            // async: false, // better go async
            data: 'q=' + query,
            type: 'POST',
            cache: false,
            success: function (data) {
                var companiesFinal = ... // snip
                process(companiesFinal);
            }
        })
    }
});

return ['test1', 'test2'];可以工作,因为随后将源功能基本上设置为:

The return ['test1', 'test2']; works, because the source function is then basically set to:

// do ajax stuff, but do nothing with the result
// return the typeahead array, which the typeahead will accept as the result:
return ['test1', 'test2'];

注释

有一个衬里可以填充companiesData:

var companiesFinal = return $.map(data, function (n, i) { n.name; });

您可能想使用var声明变量;否则,它们将具有全局范围,这会咬你.

And you probably want to declare your variables using var; otherwise they'll have global scope, which will bite you.

这篇关于具有AJAX源的Bootstrap Typeahead:未按预期返回数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆