3

ブートストラップを事前にAJAXソースで正しく動作させるのに多くの問題があります。

返される配列に警告を出すと、テストのためにハードコーディングした場合でも、まったく問題ありません。ほぼ一致を入力した場合、ほとんどの場合何も返さないか、配列からわずかな項目しか返さないようです。

これが私が現在持っているものです:

$('#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;
      }

なぜこれが正しく機能しているのか誰かが知っていますか?


これが私のPHPスクリプトから返されたオブジェクト配列の例です。ID 1および1216のオブジェクトは、先行入力ドロップダウンに表示されますが、他のオブジェクトは表示されません。なぜこれらだけが表示され、他のものは表示されないのかについて、パターンや手がかりはわかりません。

[
   {
      "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"]

誰か手がかりがありますか?なぜこれがまだ機能していないのか、私はまだ完全に無知です:(


$('#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」のコンソール出力:

[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]
4

1 に答える 1

2

更新 2

ああ、あなたのサービスは、実際にはクエリに一致しないアイテムを返しますparm。先行入力クエリは'parm'で、返された結果はどれも一致しません。matchertypeahead プラグインで使用される関数をオーバーライドできます。 docsを参照してください。return trueサービスから返されるすべての結果に一致するように実装するだけです。

更新 1

これは更新されたバージョンで、後で使用できるように名前を ID にマップします。jsfiddleが利用可能です

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、成功のコールバック内からコールバックを呼び出す必要があります。

$('#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'];ソース関数は基本的に次のように設定されるため、機能します。

// 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そして、おそらく;を使用して変数を宣言したいと思うでしょう。そうしないと、それらはグローバルスコープになり、あなたを苦しめます。

于 2013-03-15T14:58:26.200 に答える