【发布时间】:2015-04-30 13:38:31
【问题描述】:
一段时间以来,我一直对Dijit's FilteringSelect 小部件的工作方式不满意,并且一直在尝试使用Dojo 1.10 来改进它以适应我的用例。不幸的是,似乎没有一种设置组合是完全正确的,主要是因为它们不能一起工作。
- 设置
queryExpr: '*${0}*'很好,但它会让自动完成变得疯狂。 - 设置
autoComplete: true很好,只要您想从头开始输入整个文本,直到找到匹配项。不幸的是,如果您想从中间的某个地方开始,那将变得很痛苦。当然,您可以将searchDelay: N设置为足够大以捕获您所有输入的内容,但是一旦您让它在菜单中返回增量结果,BAM 您继续输入的能力并可能最终在单词的其他地方匹配走出窗外。
我真正想要的是在 shell 或像样的文本编辑器(例如 fzf)中完成的类似模糊查找器的功能。这样的查找器会跳过中间字符,基本上按字符拆分您的输入并在它们之间添加隐式通配符。您继续输入,直到第一个匹配项是您想要的,然后结束查找器并让它替换值。
我开始想办法实现这一点,但并没有走得太远。我曾想过劫持_patternToRegExp(),但很快发现我的商店(带有一些JSON 数据的dojo/data/ItemFileReadStore 实例)设置了_oldAPI 标志和that never gets executed。我很高兴更新商店,但对我来说,这并不明显会使这更容易。对我的商店进行黑客攻击后,事情变得一发不可收拾,我决定采取一种涉及更少但更黑客的方法。
如果您关闭自动完成并设置选项以在单词中间进行匹配,您会得到一个非常接近所需内容的结果列表。用户剩下要做的就是在他们输入足够的输入以获得匹配项之后以及在他们 Tab 离开之前点击一次Down。那么问题就变成了如何避免需要这种人工干预并变得更加宽容。
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?
dojo/store/Memory是您的选择,而不是dojo/data/ItemFileReadStore?它可能会在数据过滤端为您提供更多选择/灵活性...... -
@KenFranqueiro 我已使用该信息更新了问题,但我使用的是 Dojo 1.10,如果这有助于解决此问题,我很乐意使用不同的商店。我正在从数据库中动态生成 JSON 数据,但它不是很多数据,如果只有 UI 小部件最终更宽容,我可以将其转换为最有效的任何格式!
-
@KenFranqueiro 自从之前回复以来,我想从其他小部件访问这些数据,并且能够使用
dstore/legacy/DstoreAdapter将商店转换为dstore/RequestMemory以使其与dijit/FilteringSelect兼容。不确定这是否会使 this 问题变得更容易,但确实是这样。 -
不确定您要做什么,但
_patternToRegExp只是*?的简单通配符替换,它会在其周围放置锚点。它实际上很危险,因为它不考虑文字元字符。
标签: javascript regex dojo fuzzy-search dijit.form