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', "");

【讨论】:

所做的只是清空查询。它对datums 的数组没有影响...调用.typeahead('setQuery',"") 不会清空选定的项目。

以上是关于Twitter Typeahead.js - 选择时删除数据的主要内容,如果未能解决你的问题,请参考以下文章

Twitter typeahead .js 文件未更新

使用 Django 通过远程数据提高 Twitter 的 typeahead.js 性能

typeahead 表单,为用户提供提示或数据。自动补全typeahead.js

Twitter Typeahead.js:单击/聚焦时显示所有选项

使用 Twitter Typeahead.js 的多个远程源

Twitter Typeahead.js 如何返回字符串中的所有匹配元素