Twitter Typeahead.js - 选择时删除数据
Posted
技术标签:
【中文标题】Twitter Typeahead.js - 选择时删除数据【英文标题】:Twitter Typeahead.js - remove datum upon selection 【发布时间】:2014-01-29 11:03:48 【问题描述】:我正在使用 typeahead.js 0.9.3,它运行良好。我的问题是是否可以在“typeahead:selected”事件(或任何事件,就此而言)从数据集中删除数据。
我在页面加载时使用 Typeahead 的 prefetch
选项获取数据集中的数据。我知道我可以调用$('selector').typeahead('destroy')
并重新初始化打字头并在prefetch
对象中使用filter
,但是不得不重新调用数据似乎相当重要(我们没有将数据缓存在本地存储)。
我想我正在寻找类似于 filter
函数的东西来遍历数据数组并删除先前选择的(或所有选择的)数据。看起来在 typeahead 中没有公共函数可以执行此操作,但也许我错过了。
我已通读 typeahead 的文档并在此处搜索,但没有找到答案。
编辑:我通过从prefetch
切换到local
并使用AJAX post
调用来获取数据,将其设置为全局变量,然后将其传递给typeahead
,从而解决了当前的问题。可以从全局数据数组中添加/删除项目,然后根据需要销毁/重新初始化 typeahead。远非理想,但它确实有效。
【问题讨论】:
为什么不在将数据传递到预输入之前过滤数据? 因为没有机制可以“重新过滤”它而不调用.typeahead('destroy')
并使用另一个 prefetch
调用重新初始化 typeahead
。我不想在typeahead:selected
事件之后再去POST
。
【参考方案1】:
您可以在 Typeahead 0.10 中对任何 Bloodhound 数据集(无论是远程的、预取的还是本地的)实现此功能。
只需跟踪独立于 Bloodhound 数据集选择的数据,不要使用 Bloodhound#ttAdapater()
作为您的预输入源。 ttAdapter 方法只是 Bloodhound#get(query, cb)
的包装器——因此,可以直接调用 get(query, cb)
并使用自定义回调来代替它,该回调会检查每个建议是否与当前选择相匹配。
这是一个 JSFiddle — http://jsfiddle.net/likeuntomurphy/tvp9Q/
var selected = [];
var select = function(e, datum, dataset)
selected.push(datum.val);
$("#selected").text(JSON.stringify(selected));
$("input.typeahead").typeahead("val", "");
var filter = function(suggestions)
return $.grep(suggestions, function(suggestion)
return $.inArray(suggestion.val, selected) === -1;
);
var data = new Bloodhound(
name: 'animals',
local: [ val: 'dog' , val: 'pig' , val: 'moose' ],
datumTokenizer: function(d)
return Bloodhound.tokenizers.whitespace(d.val);
,
queryTokenizer: Bloodhound.tokenizers.whitespace,
// custom suggestion filter is applied after Bloodhound
// limits the set of possible suggestions
// see comment by Basti below
limit: Infinity
);
data.initialize();
$('input.typeahead').typeahead(null,
name: 'animals',
displayKey: 'val',
/* don't use
source: data.ttAdapter(), */
source: function(query, cb)
data.get(query, function(suggestions)
cb(filter(suggestions));
);
,
templates:
empty: '<div class="empty-message">No matches.</div>'
).bind('typeahead:selected', select);
【讨论】:
这非常有效。我已经寻找了很多解决方案(当我知道我的远程源中没有更多结果时,我不想在每个 typeahead 事件上完全清除缓存)。很好的答案! :) 一个重要的补充:您还应该将 Bloodhound 的限制选项设置为非常大,甚至无限,因为在调用自定义过滤器之前应用了建议限制。最坏的情况:在 100 个可能的结果中,您可以使用自定义过滤器过滤掉 5 个,但 Bloodhound 只为您提供这 5 个,因为建议限制导致结果为空。 出色的收获!我还没有使用具有足够大数据集的 Bloodhound,因此需要限制。 只是对此的一个小更新,而不是使用 jQuery 的 val,他们建议使用$('.typeahead').typeahead('val', myVal);
,因为它看起来在当前版本中有点中断。 github.com/twitter/typeahead.js/blob/master/doc/…
感谢您的建议,它成功了!但请注意,在当前版本的 Bloodhound (0.11.1) 中,您必须使用 data.search
而不是 data.get
来获取匹配项目的列表。另外,请注意,上述filter
函数中的suggestion.val
正在访问Bloodhound 数据源值的val
属性。如果您有任何其他属性来保存您的数据,则需要对其进行调整(这可能是初学者的错误,但我需要几分钟来搜索它)【参考方案2】:
正如您所指出的,如果不对当前的预输入版本进行大规模黑客攻击,即使不是不可能,这也是很棘手的。 你需要三样东西:
-
Remote 作为函数选项(您可以在其中实现自己的 getter 函数来访问您的数据、过滤查询并删除您已经选择的项目。
缓存控制:拒绝预先输入控制以将缓存用于最后执行的建议搜索的能力。
按需建议搜索,仅在需要时刷新建议结果(当您输入输入框并开始输入查询时)。
下一个 typeahead 版本(目前正在开发中的 0.10)可能支持所需的功能。 但是......碰巧我的(Svakinn)typeahead fork 支持您需要的所有三个条件。 您的配置应提供 getter 函数,您可以在其中从初始化数据中选择基准,并通过查询字符串和已选择的选项对其进行过滤。
remote: yourGetterFunction
那么你需要禁用建议缓存:
skipCache: true
如果您不想等待下一个 typeahead 版本,我建议您尝试一下:https://github.com/Svakinn/typeahead.js/tree/typeaheadSimple 还有现场直播的 JQuery 和 Knockout 示例可用:https://github.com/Svakinn/typeahead.js/blob/typeaheadSimple/Examples.md
【讨论】:
这看起来很棒 - 我现在正在测试您的解决方案。【参考方案3】:试试这个,它对我有用。
$('#selector').typeahead('setQuery', "");
【讨论】:
所做的只是清空查询。它对datum
s 的数组没有影响...调用.typeahead('setQuery',"")
不会清空选定的项目。以上是关于Twitter Typeahead.js - 选择时删除数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django 通过远程数据提高 Twitter 的 typeahead.js 性能
typeahead 表单,为用户提供提示或数据。自动补全typeahead.js
Twitter Typeahead.js:单击/聚焦时显示所有选项