Я был недоволен тем, как Dijit's FilteringSelect Виджет работает некоторое время, и я возился с Dojo 1.10, пытаясь улучшить его для моего варианта использования. К сожалению, кажется, что никакая комбинация настроек не является правильной, в основном потому, что они не работают вместе.
- Настройка
queryExpr: '*${0}*'
хороша, но делает автозаполнение безумным. - Установка
autoComplete: true
удобна, если вы хотите вводить весь текст, начиная с начала, пока не найдете совпадение. К сожалению, если вы хотите начать где-то посередине, это становится головной болью. Конечно, вы можете установитьsearchDelay: N
на что-то достаточно большое, чтобы уловить весь ваш ввод, но как только вы позволите ему возвращать инкрементальные результаты в меню, БАМ ваша способность продолжать печатать и, возможно, в конечном итоге совпадение где-то еще в слове исчезает окно.
Что мне действительно нужно, так это то, что работает так же, как нечеткий поиск в оболочке или приличном текстовом редакторе (например, fzf а>). Такие средства поиска пропускают промежуточные символы, в основном разделяя ввод по символам и добавляя между ними неявные подстановочные знаки. Вы продолжаете вводить текст до тех пор, пока первое совпадение не будет тем, которое вам нужно, затем завершите поиск и позвольте ему заменить значение.
Я начал возиться с тем, как это реализовать, но далеко не продвинулся. Я думал об угоне _patternToRegExp()
, но быстро обнаружил, что мой store (экземпляр dojo/data/ItemFileReadStore
с некоторыми данными JSON) устанавливает флаг _oldAPI и который никогда не исполняется. Я счастлив обновлять магазины, но для меня не очевидно, что это упростит. В результате взлома моего магазина все вышло из-под контроля, и я решил применить менее сложный, но более хакерский подход.
Если вы отключите автозаполнение и установите параметры для сопоставления в середине слов, вы получите список результатов, довольно близкий к тому, что необходимо. Все, что остается сделать пользователю, - это нажать Down один раз после того, как он наберет достаточно ввода, чтобы получить совпадение, и до того, как они Tab уйдут. Тогда возникает вопрос, как избежать необходимости этого ручного вмешательства и стать более снисходительным.
define(["dijit/form/FilteringSelect"], function(FilteringSelect){
return declare("alerque.FuzzyFilter", [FilteringSelect], {
autoComplete: false,
highlightMatch: 'all',
ignoreCase: true,
queryExpr: '*${0}*',
searchDelay: 0,
_patternToRegExp: function(qs) {
// If this ever actually got called, maybe we could
// return qs split with wild cards between all characters
return this.inherited(arguments);
},
onblur: function() {
this._autoCompleteText(this.get('displayedValue'));
// Pick first match from menu
return this.inherited(arguments);
}
})});
Перехват функции onblur()
кажется правильным местом для создания виджета, который по умолчанию использует первое совпадение, если вы нажмете табуляцию или щелкнете мышью, но я не могу понять, как на самом деле использовать первое совпадение из меню.
Как мне перейти к более надежному нечеткому поиску с автозаполнением наилучшего соответствия? Мне не нужен ComboBox, значение должно в конечном итоге быть одним из значений в моем наборе данных JSON. В то же время я хочу, чтобы параметры ввода были гораздо более неряшливыми, чем ввод значения с самого начала или необходимость вручную выбирать совпадение.
dojo/store/Memory
вариант для вас вместоdojo/data/ItemFileReadStore
? Это может дать вам больше возможностей / гибкости в конце фильтрации данных ... - person Ken Franqueiro   schedule 30.04.2015dstore/RequestMemory
с помощьюdstore/legacy/DstoreAdapter
, чтобы сделать его совместимым сdijit/FilteringSelect
. Не уверен, что это облегчит эту проблему, но это кое-что. - person Caleb   schedule 06.05.2015_patternToRegExp
просто замена подстановочного знака*?
, которая сбрасывает якоря вокруг него. Это действительно опасно, так как не учитывает буквальные метасимволы. - person   schedule 04.06.2015