0

我是使用 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"}
]}

我有预先输入的捆绑包 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 控制台给了我:

未捕获的类型错误:无法读取未定义的属性“长度”

但那是在我的 jquery.2.1(缩小)库中,而不是上面的 js 源。#tbSearch浏览器在输入下方不显示弹出窗口。

正如@Mike 建议的那样,jsfiddle http://jsfiddle.net/gw0sfptd/1/但我必须修改一些东西才能使用本地json。这也不起作用大声笑

按照大卫的建议进行编辑,我应该清理我的 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 控制台中没有工作输入和没有(可用)错误。我想要的输出将是产品代码列表,还有它们所在的类别和 gtin13(如果不是 null),因为 sql 搜索所有这三个选项。我应该在客户端为产品创建一个 javascript“类”并将 json 解析为它吗?我仍然不清楚整个猎犬的工作原理。(是的,我查看了样本并阅读了 typeahead 和 Bloodhound 的文档)我不知道这是否可能,但我的最终愿望是,当您从 typeahead 建议中选择一个项目时,此 productdatasource 链接到 productdetail .aspx 并且如果您选择 categorydatasource 的一个项目(在这个问题中不可见),它将页面重定向到 categorydetail.aspx

我的 chrome 控制台错误

4

2 回答 2

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(!)也没有。

您应该能够参考我的示例和这个答案来获得使用远程工作的提前输入。

于 2014-11-01T00:47:02.653 回答
0

伯吉是对的。你已经固定了大写而不是复数:它应该是data.Product,不是data.Products。或者您引用的 JSON 可能只是data.Products,在这种情况下,数组是data.Products.Product.

獾和阵列

你应该注意的另一件事。看起来这里的 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"},
        ]
    }
}

但是只有一种产品,badgerfish 不会知道将其变成一个数组,你会得到这个:

{
    "Products": {
        "Product": {"@ProductCode":"C1010","@CategoryName":"Clips"}
    }
}

并且没有产品,它根本不知道包括"Product"

{
    "Products": {}
}

结果是您可能应该为这些情况做好准备。同样,在我看来,displayKey除非它只接收一个产品,否则该函数会抛出异常。

我在一个项目中工作,我们的 nodejs 服务器连接到后端服务器。这些后端传统上使用 XML,但现在可以选择使用 badgerfish 响应 JSON。数组的这种情况非常普遍,以至于我们有一个实用函数,它将data.Products.Product作为参数并将其转换为数组,如果它还不是一个数组。

于 2014-11-01T12:36:18.640 回答