我正在使用 Typeahead.js 在我们的 webapp 中搜索产品。我们目前正在使用 Bloodhound 远程获取建议。在服务器中,我正在使用用户输入的字符串进行数据库查询。但我怀疑,使用 Bloodhound 的想法不是在服务器中这样做......
我的JS代码如下:
var products = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('value'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 205,
prefetch: 'Product/GetData?q=&ft=true',
remote: 'Product/GetData?q=%QUERY'
});
products.initialize();
$('#the-basics .typeahead').typeahead(null, {
name: 'products',
displayKey: 'name',
source: products.ttAdapter(),
minLength: 3,
templates: {
empty: [
'<div class="empty-message">',
'No products for current query',
'</div>'
].join('\n'),
suggestion: Handlebars.compile('<p><strong>{{name}}</strong></p>')
}
});
我的产品控制器中有一个操作来检索产品列表......所以在 Prefetch 我只返回 ACTIVE 产品......但是你是否在文本框中写了一些东西,远程选项被触发并返回所有匹配查询。
我的 GetData 操作代码:
public virtual JsonResult GetData(string q, bool ft = false)
{
if (ft == true)
{
var fetchTag = db.Products.AsNoTracking()
.Where(x => x.Active == true && x.idTenant == CurrentTenantID)
.OrderByDescending(x => x.Active).ThenBy(x => x.Nombre)
.Take(20)
.Select(x => new TagSys() { tag = x.idCaballo, name = x.Nombre }).ToList();
return Json(fetchTag, JsonRequestBehavior.AllowGet);
}
else
{
var fetchTag = db.Products.AsNoTracking()
.Where(x => x.idTenant == CurrentTenantID && x.Nombre.StartsWith(q.ToLower()))
.OrderByDescending(x => x.Active).ThenBy(x => x.Nombre)
.Take(20)
.Select(x => new TagSys() { tag = x.idCaballo, name = x.Nombre }).ToList();
return Json(fetchTag, JsonRequestBehavior.AllowGet);
}
}
第一个问题:[已解决]尽管查询在 Prefetch 数据中输入了匹配的值,但它从远程数据中返回值。为什么是这样?解答:Bloodhound 标记器需要一个数据字段/属性作为参数。“值”不是我的数据中的属性......在我的卡索中更改为“名称”解决了这个问题。
第二:我应该使用用户在远程方法中输入的查询值来查询数据库,还是应该返回一个大列表让Bloodhound完成工作?
第三:[已解决]我使用了该minLength: 3
选项,希望它会在输入中的 3 个字符后开始建议/搜索,但我看到它是在按下第一个键后触发的。回答:此选项是顶级的,与数据集无关,因此在我的代码中,我将null
typeahead init 中的参数替换为{ minLength: 3}
并且它有效。