Typeahead.js — поиск по нескольким значениям свойств

См. пример ниже.

JSFiddle: http://jsfiddle.net/R7UvH/2/

Как заставить typeahead.js (0.10.1) искать совпадения в более чем одном значении свойства? В идеале в целом data (data.title, data.desc и во всех data.category[i].name)

 datumTokenizer: function(data) {
     // **search in other property values; e.g. data.title & data.desc etc..**
     return Bloodhound.tokenizers.whitespace(data.title);
 },

Весь пример:

var data = [{
    title: "some title here",
    desc: "some option here",
    category: [{
        name: "category 1",
    }, {
        name: "categoy 2",
    }]
},
{
    title: "some title here",
    desc: "some option here",
    category: [{
        name: "category 1",
    }, {
        name: "categoy 2",
    }]
}];

var posts = new Bloodhound({
    datumTokenizer: function(data) {
        // **search in other property values; e.g. data.title & data.desc etc..**
        return Bloodhound.tokenizers.whitespace(data.title);
    },
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
});
posts.initialize();

$('#search-input').typeahead({
    highlight: true
}, {
    name: 'Pages',
    displayKey: 'title',
    source: posts.ttAdapter(),
    templates: {
        header: '<h3>Pages</h3>'
    }
});

person Iladarsda    schedule 18.02.2014    source источник


Ответы (3)


В Typeahead 0.10.3 добавлена ​​"поддержка объекта токенизаторы для токенизации нескольких свойств."

Итак, ваш пример становится

var posts = new Bloodhound({
    datumTokenizer: Bloodhound.tokenizers.obj.whitespace('title', 'desc'),
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: data
});

Однако я не думаю, что это будет работать для свойств, вложенных внутрь, то есть для объекта data.category в вашем случае.

В качестве примечания, если вы используете предварительно загруженные данные, обязательно сначала очистите локальное хранилище, иначе новый токенизатор не вступит в силу (поскольку datumTokenizer используется при добавлении в поисковый индекс, и если данные уже присутствуют в localStorage , то поисковый индекс обновляться не будет). Я застрял на этом некоторое время!

person Neelabh    schedule 29.09.2014
comment
продолжал работать над решением @timothy в течение нескольких дней, но у меня это не сработало. Это решение работает и является более элегантным. - person Hammad Khan; 09.11.2014
comment
Отличное решение, спасибо. Примечание: вы можете предотвратить кэширование предварительной выборки с помощью prefetch: { cache: false, ... } - person Sean Connolly; 23.03.2016
comment
Это работает, но предупреждает: необходимо указывать свойства в том порядке, в котором они появляются в схеме данных; в противном случае это не сработает. Я думаю, что это ошибка в шрифте, так как это удивляет пользователя. - person toddmo; 22.03.2017

return Bloodhound.tokenizers.whitespace(data.title) возвращает массив строк.

Итак, вместо того, чтобы возвращать это значение: сохраните его (и другие желаемые значения), затем соедините их и верните это значение...

x = Bloodhound.tokenizers.whitespace(data.title);
y = Bloodhound.tokenizers.whitespace(data.desc);
z = Bloodhound.tokenizers.whitespace(data.category[i].name);
return x.concat(y).concat(z);
person Timothy Aaron    schedule 04.04.2014

Я реализовал решение здесь:

http://jsfiddle.net/Fresh/4nnnG/

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

$('#search-input').typeahead({
    highlight: true
}, {
    name: 'titles',
    displayKey: 'title',
    source: titles.ttAdapter()
}, {
    name: 'descs',
    displayKey: 'desc',
    source: descs.ttAdapter()
}, {
    name: 'cats',
    displayKey: 'name',
    source: cats.ttAdapter()
});
person Ben Smith    schedule 18.02.2014
comment
@NullSoulException :D - person Ben Smith; 19.02.2014
comment
@Fresh спасибо, что нашли время, это немного сложнее, чем я изначально представлял. Я использую несколько источников (которые классифицируются с помощью заголовков - точно так же, как в демонстрации с несколькими источниками typeahead.js twitter.github.io/typeahead.js/examples). Можете ли вы указать мне пример использования фильтра? Обратите внимание, что я хочу сохранить категоризацию с заголовками (медиа, страницы, посты). Благодарность - person Iladarsda; 19.02.2014
comment
Я изучал способ filter() и то, что, как я думал, поможет вам, не сработает, т.е. создаст список токенов в фильтре. Я думаю, вам следует реализовать решение, используя способ, который я предложил в своем ответе, за исключением того, что вам нужно будет добавить заголовки категоризации, как вы предложили. Надеюсь, вы найдете решение, и мне будет интересно его увидеть! - person Ben Smith; 20.02.2014