2014-10-31 51 views
0

我是使用typeahead插件的新手,我的javascript(而不是jquery)技能很糟糕。這是我的JSON:解析鍵入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的控制檯給我:

Uncaught TypeError: Cannot read property 'length' of undefined

但是,這是我的jquery.2.1(minified)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控制檯沒有(可用)錯誤。 我希望的輸出將是產品代碼列表,但也是它們所在的類別以及gtin13(如果不爲空),因爲sql會搜索所有這三個選項。我應該在客戶端爲產品製作一個javascript'class'並解析json嗎?我還不清楚全血獵犬的工作原理。 (是的,我已經看過樣品,並閱讀了打字和獵頭的文檔)我不知道這是否可能,但我最終的願望是,當您從鍵入的建議中選擇一個項目時,此產品數據源鏈接到productdetail的.aspx如果你選擇categorydatasource的項目(在此問題visisble),它重定向頁面categorydetail.aspx

my chrome console error

+1

您可能想返回'data.Product'而不是'data.products'? – Bergi 2014-10-31 13:25:23

+0

謝謝,但沒有解決它。 'return data.Products;' – 2014-10-31 13:41:02

+0

你可能想把這些全部粘貼到一個jsfiddle中,並將它鏈接到這裏。 – 2014-10-31 13:44:18

回答

1

我寫了一個小提琴來演示如何使用JSON(本地,而不是遠程,例如)typeahead.js:

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

除非在JSON.parse期間引發JavaScript錯誤,否則完全可以擁有任何屬性名稱字符。您可以執行'data.Product [0] [「@ ProductCode」]來訪問該值。 – 2014-11-01 01:45:44

+1

我同意格雷格。 「@ProductCode」不是一個有效的變量名,但它在JSON中作爲一個字符串以及作爲對象鍵非常合適。 – 2014-11-01 01:49:09

+0

@GregBurghardt如果您嘗試在上面的代碼中使用「value:product。@ ProductCode」,jslint會突出顯示該錯誤。您還會在該行的瀏覽器控制檯中收到「Uncaught SyntaxError:Unexpected token ILLEGAL」。 – 2014-11-01 01:49:40

0

Bergi是對的。您已經確定了大寫但不是多元化:它應該是data.Product,而不是data.Products。或者你引用的JSON只是data.Products,在這種情況下,陣列是data.Products.Product

BADGERFISH和數組

還有一件事你應該知道的。它看起來像這裏的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作爲參數,並將其轉換爲數組(如果它不是一個數組)。

+0

是的,這不是最好的JSON,但很容易將XML轉換爲JSON。http://stackoverflow.com/questions/26605493/xdocument-or-xmldocument-to-json-with-c-sharp,所以我最終得到了醜陋的json。對不起,也許我應該將我的sql結果解析爲'List '並將其轉換爲json。 – 2014-11-03 08:37:38