我是使用typeahead插件的新手,我的javascript(不是jquery)技能很糟糕。这是我的JSON:
{"Product":[
{"@ProductCode":"C1010","@CategoryName":"Clips"},
{"@ProductCode":"C1012","@CategoryName":"Clips"},
{"@ProductCode":"C1013","@CategoryName":"Clips"},
{"@ProductCode":"C1014","@CategoryName":"Clips"},
{"@ProductCode":"C1015","@CategoryName":"Clips", "EAN":"0987654321"}
]}
我有typeahead包0.10.5这是我的js:
$(document).ready(function () {
var products = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 100,
remote: {
url: 'TypeAhead.ashx?q=%QUERY&cat=prod',
filter: function (data) {
return data.Products;
}
}
});
products.initialize();
$("#tbSSearch").typeahead({
highlight: true,
minLength: 2
}, {
source: products.ttAdapter(),
displayKey: function (products) {
return products.product.code;
},
templates: {
header:"<h3>Products</h3>"
}
});
});
Chrome控制台让我:
未捕获的TypeError:无法读取未定义的属性“长度”
但那是在我的jquery.2.1(缩小的)lib而不是上面的js源代码。浏览器在#tbSearch
输入下方没有显示弹出窗口。
正如@Mike建议的那样,jsfiddle http://jsfiddle.net/gw0sfptd/1/但我必须修改一些东西才能使用本地json。这也不起作用LOL
大卫建议编辑,我应该清理我的json。所以现在是:
[{"Code":"C1010","Gtin13":0,"CategoryName":"Clips"},
{"Code":"C1012","Gtin13":0,"CategoryName":"Clips"},
{"Code":"C1013","Gtin13":0,"CategoryName":"Clips"}]
和js:
remote: {
url: 'TypeAhead.ashx?q=%QUERY&cat=prod',
filter: function (products) {
return $.map(products.results, function (product) {
return {
value: product.Code
};
});
}
}
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
但是在firefox控制台中没有工作的typeahead和no(可用)错误。 我想要的输出是产品代码列表,但也是它们所在的类别和gtin13(如果不是null),因为sql搜索所有这三个选项。我应该在客户端为产品创建一个javascript“类”并将json解析为它吗?我还不清楚整个猎犬是如何运作的。 (是的,我查看了样本并阅读了typeahead和bloodhound的文档)我不知道是否可能,但我最终的愿望是,当你从typeahead建议中选择一个项目时,这个产品资源链接到productdetail .aspx并且如果你选择categorydatasource的一个项目(在这个问题中不可见),它将页面重定向到categorydetail.aspx
答案 0 :(得分:1)
我写了一个小提琴来演示如何使用typeahead.js来使用你的JSON(本地而不是远程的例子):
http://jsfiddle.net/Fresh/f9rbeqyc/
在下面的回答中,我选择使用ProductCode作为建议,但如果需要,您显然可以使用CategoryName。
我使用的代码的关键部分以及一些注释在这里:
var json = '{"Product":[ ' +
'{"@ProductCode\":\"C1010\",\"@CategoryName\":\"Clips\"},' +
'{"@ProductCode\":\"C1012\",\"@CategoryName\":\"Clips\"},' +
'{"@ProductCode\":\"C1015\",\"@CategoryName\":\"Clips\", \"EAN\":\"0987654321\"}]}';
// Parse the JSON string to a JSON object
var jsonObject = JSON.parse(json);
var products = new Bloodhound({
// Use $.map() to create an array of ProductCode key value pairs
local: $.map(jsonObject.Product, function (product) {
return {
value: product["@ProductCode"]
};
}),
datumTokenizer: function (datum) {
// Specify the variable within the datum to use as suggestion data
// In this case it's the value
return Bloodhound.tokenizers.whitespace(datum.value);
},
queryTokenizer: Bloodhound.tokenizers.whitespace
});
另请注意,datumTokenizer指定要用作建议的值;创建了一个带有名为“value”的键的基准数组,因此我们希望使用“value”作为显示键。在您的示例中,您有“return products.product.code;”这不会起作用,因为你的基准没有一个叫做“代码”的字段,也没有你的JSON(!)。
您应该可以参考我的示例和this回答来获取使用远程工作的预先输入。
答案 1 :(得分:0)
Bergi是对的。您已经确定了大写字母而不是复数:它应该是data.Product
,而不是data.Products
。或者你引用的JSON只是data.Products
,在这种情况下,数组是data.Products.Product
。
BADGERFISH和ARRAYS
你应该注意的另一件事。看起来这里的JSON来自badgerfish。我不知道你是否知道这意味着什么 - 基本上它是将XML翻译成JSON的一种方式。如果只有一个产品或根本没有产品,格式将不同。例如,以下XML:
<Products>
<Product ProductCode="C1010" ="Clips"/>
<Product ProductCode="C1012" ="Clips"/>
</Products>
将提供以下JSON:
{
"Products": {
"Product": [
{"@ProductCode":"C1010","@CategoryName":"Clips"},
{"@ProductCode":"C1012","@CategoryName":"Clips"},
]
}
}
但只有一种产品,獾鱼不会知道它是一个阵列,你得到这个:
{
"Products": {
"Product": {"@ProductCode":"C1010","@CategoryName":"Clips"}
}
}
并且没有产品,根本不知道包含"Product"
:
{
"Products": {}
}
结果是你应该为这些案件做准备。同样,在我看来,函数displayKey
将抛出异常,除非它只收到一个产品。
我在我们的nodejs服务器连接到后端服务器的项目上工作。这些后端传统上使用XML,但现在可选择使用badgerfish使用JSON进行响应。数组的这种情况是如此常见,以至于我们有一个实用函数,它将data.Products.Product
作为参数并将其转换为数组,如果它不是一个数组。