Twitter Typeahead Bloodhound:在sorter中获取当前搜索框的搜索字符串
Hey Bernd,我完全懂你的烦恼——页面上有多个搜索框时,直接用类选择器$('.searchfield').val()拿值确实会混乱,根本没法确定用户正在操作哪一个。咱们可以从Bloodhound和Typeahead的绑定逻辑入手,用以下两种方法解决:
方法一:为每个搜索框创建独立的Bloodhound实例
这是最稳妥的方案,因为每个搜索框都拥有专属的Bloodhound实例,sorter里可以直接通过闭包捕获当前输入框的引用,精准拿到对应的值:
$('.searchfield').each(function() { // 捕获当前搜索框的DOM引用 var $currentInput = $(this); // 为当前搜索框创建专属的Bloodhound实例 var suggestions = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), queryTokenizer: Bloodhound.tokenizers.whitespace, source: /* 你的数据源 */, sorter: function(a, b) { // 直接用当前输入框的引用获取值,不会和其他搜索框混淆 var input_string = $currentInput.val(); input_string = input_string.split(/[ \-]+/); input_string = input_string[0].toLowerCase(); var aArray = a.name.toLowerCase().split(/[ \-]+/); var bArray = b.name.toLowerCase().split(/[ \-]+/); var apos = 0, bpos = 0; for (var i = 0; i < aArray.length; i++) { if (aArray[i].indexOf(input_string) !== -1) { apos = i; break; } } for (i = 0; i < bArray.length; i++) { if (bArray[i].indexOf(input_string) !== -1) { bpos = i; break; } } return apos < bpos ? -1 : (apos > bpos ? 1 : 0); } }); // 初始化当前搜索框的Typeahead $currentInput.typeahead({ hint: true, highlight: true, minLength: 1 }, { name: 'suggestions', source: suggestions, display: 'name' }); });
方法二:复用Bloodhound实例,通过事件传递当前输入值
如果不想创建多个Bloodhound实例,也可以借助Typeahead的typeahead:as-you-type事件,把当前活跃搜索框的输入值存到Bloodhound实例上,供sorter读取:
// 创建共享的Bloodhound实例 var suggestions = new Bloodhound({ datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), queryTokenizer: Bloodhound.tokenizers.whitespace, source: /* 你的数据源 */, sorter: function(a, b) { // 读取之前存储的当前输入值,做个容错处理 var input_string = this._currentInputValue; if (!input_string) return 0; input_string = input_string.split(/[ \-]+/); input_string = input_string[0].toLowerCase(); var aArray = a.name.toLowerCase().split(/[ \-]+/); var bArray = b.name.toLowerCase().split(/[ \-]+/); var apos = 0, bpos = 0; for (var i = 0; i < aArray.length; i++) { if (aArray[i].indexOf(input_string) !== -1) { apos = i; break; } } for (i = 0; i < bArray.length; i++) { if (bArray[i].indexOf(input_string) !== -1) { bpos = i; break; } } return apos < bpos ? -1 : (apos > bpos ? 1 : 0); } }); // 为每个搜索框绑定Typeahead并监听输入事件 $('.searchfield').each(function() { var $currentInput = $(this); $currentInput.typeahead({ hint: true, highlight: true, minLength: 1 }, { name: 'suggestions', source: suggestions, display: 'name' }).on('typeahead:as-you-type', function(e, query) { // 把当前输入的内容存到Bloodhound实例上 suggestions._currentInputValue = query; }); });
两种方法里,我更推荐第一种,因为它完全避免了多个搜索框之间的状态冲突,逻辑更清晰,维护起来也更简单。
内容的提问来源于stack exchange,提问作者Bernd M.
相关产品推荐
相关产品推荐

