Как составить список объектов для Typeahead.js и/или движка Bloodhound?

Мне трудно понять, как отобразить список объектов, используя typeahead с файлом json в качестве источника. Мои данные не отображаются.

Я хочу перечислить имена и использовать другие атрибуты для других целей при выборе.

../data/test.json

[   
    {"name": "John Snow", "id": 1},
    {"name": "Joe Biden", "id": 2},
    {"name": "Bob Marley", "id": 3},
    {"name": "Anne Hathaway", "id": 4},
    {"name": "Jacob deGrom", "id": 5}
]

test.js

$(document).ready(function() {
    var names = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.whitespace("name"),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        prefetch: {
          url: '../data/test.json'
        }
    });
    names.initialize();

    $('#test .typeahead').typeahead({
        name: 'names',
        displayKey: 'name',
        source: names.ttAdapter()
    });
)};

test.html

<div id="test">
    <input class="typeahead" type="text">
</div>

** И если кто-то может объяснить мне, что такое datumTokenizer и queryTokenizer, это было бы здорово **


person Vongdarakia    schedule 07.10.2014    source источник


Ответы (2)


Файл JSON содержит массив объектов JSON, но механизм предложений Bloodhound ожидает массив объектов JavaScript.

Следовательно, вам нужно добавить фильтр в объявление предварительной выборки:

prefetch: {
 url: '../data/test.json',
 filter: function(names) {
   return $.map(names, function(name) { 
    return { name: name };
 });
}

Что касается «datumTokenizer», его цель состоит в том, чтобы определить, как данные (т.е. предполагаемые значения) должны быть токенизированы. Именно эти токены затем используются для поиска соответствия входному запросу.

Например:

Bloodhound.tokenizers.whitespace("name")

Это принимает данные (в вашем случае значение имени) и разбивает его на два токена, например. «Боб Марли» будет разделен на два токена: «Боб» и «Марли».

Вы можете увидеть, как работает токенизатор пробелов, просмотрев исходный код typeahead. :

function whitespace(str) {
 str = _.toStr(str);
 return str ? str.split(/\s+/) : [];
}

Обратите внимание, как он разбивает данные, используя регулярное выражение для пробелов (\s+, т.е. одно или несколько вхождений пробелов).

Точно так же «queryTokenizer» также определяет, как токенизировать поисковый запрос. Опять же, в вашем примере вы используете токенизатор пробелов, поэтому поисковый запрос «Боб Марли» приведет к данным «Боб» и «Марли».

Следовательно, с определенными токенами, если вы будете искать «Марли», совпадение будет найдено для «Боба Марли».

person Ben Smith    schedule 07.10.2014
comment
Спасибо за объяснение токенизаторов, это было полезно. Но меня смущает ваше утверждение: файл JSON содержит массив строк, но механизм предложений Bloodhound ожидает объекты JavaScript. Мой файл JSON содержит список объектов, а не строк. - person Vongdarakia; 08.10.2014
comment
Извините, он должен сказать, что содержит массив объектов JSON (я обновил свой ответ). Для Bloodhound требуются объекты JavaScript, поэтому для создания массива объектов JavaScript используется вызов $.map(). - person Ben Smith; 08.10.2014
comment
А, теперь это имеет смысл. Я не знал разницы между объектами JSON и Javascript. Наконец-то все работает как надо! Большое спасибо! Вы были полезны! - person Vongdarakia; 09.10.2014
comment
@ user3228667 Рад, что смог помочь :) - person Ben Smith; 09.10.2014
comment
Я считаю, что filter: стало transform: в более поздних версиях. - person Kirkman14; 24.01.2017

У меня есть более простой вариант, то, что вы сделали правильно, за исключением одной маленькой ошибки. На самом деле вы можете использовать массив объектов, как вы показали.

Замените displayKey: 'name' на display: 'name' и все должно работать.

Таким образом, полная функция typeahead будет выглядеть так:

$('#test .typeahead').typeahead({
    name: 'names',
    display: 'name',
    source: names.ttAdapter()
});
person Saahithyan Vigneswaran    schedule 10.07.2017