如何将 Twitter typeahead.js 与 Microsoft OData API 一起使用?

How do I use Twitters typeahead.js with Microsoft OData API's?

我在编写 Web 应用程序以从我们的 CRM 应用程序中获取 JSON 数据时遇到了 运行 问题。

我想做的是使用 Twitter's typeahead.js 插件从我们的 CRM 应用程序远程获取客户信息。 Microsoft 确实提供了一种使用 JSON 数据进行通信的方法。他们称之为 OData。但是,这看起来不像您典型的 JSON 响应。这就是为什么我无法使用它设置 typeahead 插件的原因。

当我向 API URL 发送 GET 请求时,我收到以下响应:

{
    "d":{
        "results":[
            {
                "__metadata":{
                    "uri":"http://*****/*****/XRMServices/2011/OrganizationData.svc/AccountSet(guid'de227fde-fb40-dd11-b5d3-001cc46325e5')",
                    "type":"Microsoft.Crm.Sdk.Data.Services.Account"
                },
                "Name":"Some company as",
                "AccountId":"de227fde-fb40-dd11-b5d3-001cc46325e5"
            },
            {
                "__metadata":{
                    "uri":"http://*****/*****/XRMServices/2011/OrganizationData.svc/AccountSet(guid'5dc70a19-e91e-e311-9ad7-005056ac083a')",
                    "type":"Microsoft.Crm.Sdk.Data.Services.Account"
                },
                "Name":"Compnay AS",
                "AccountId":"5dc70a19-e91e-e311-9ad7-005056ac083a"
            }
        ]
    }
}

所以问题来了: 如何设置 Twitter 的 typeahead 插件以使用此数据结构?

在显示建议时,我想要 JSON 响应中的 Name 值。我想在选择建议时获取关联的 AccountId 值。

到目前为止,这是我在代码中得到的:

HTML:

<!DOCTYPE html>
<html lang="no">
    <head>
        <title>Company :: Time Registrering</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" type="text/css" href="css/global.css" />
    </head>
    <body>

        <form action="" method="GET" autocomplete="off">
            <input type="text" name="account" id="account" placeholder="Kunde...">
        </form>

        <script type="text/javascript" src="js/jquery.min.js"></script>
        <script type="text/javascript" src="js/typeahead.js"></script>
        <script type="text/javascript" src="js/global.js"></script>
    </body>
</html>

JavaScript: (js/global.js)

$(document).ready(function () {
    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: "http://*****/*****/xrmservices/2011/OrganizationData.svc/AccountSet?$select=Name,AccountId&$filter=substringof('%QUERY',Name) and StateCode/Value eq 0"
    });

    accounts.initialize();

    $("#account").typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    }, {
        name: 'account',
        displayKey: 'd.results[0].Name',
        source: accounts.ttAdapter()
    });

});

但是:我的代码不起作用。我得到的只是在输入字段下显示 "undefined" 的文本。我怀疑我的 datumTokenizerdisplayKey 引用不正确。我不完全理解datumTokinizer。因此,如果有人可以启发我,我将不胜感激:)

你应该使用过滤器并使用 jQuery.map

html

 <input type="text" name="account" id="account" placeholder="Kunde..." />

js

$(document).ready(function () {



    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
        url : "https://gist.githubusercontent.com/anonymous/80a75d841a055ea0e480/raw/4eb8d4f1833d8a15cae1830097c090f5d581bd12/gistfile1.txt",
        filter: function(jsonValue) {

                return $.map(jsonValue.d.results, function (result) {
                return {
                    value: result.Name
                };
            });
        }
    }     


    });

    accounts.initialize();

    $("#account").typeahead({
        hint: false,
        highlight: true,
        minLength: 2
    }, {
        source: accounts.ttAdapter()
    });

});

Fiddle here

我找到了解决问题的方法。我注意到我可以在 Bloodhound 对象中使用过滤器函数并生成一个带有 $.map 的数组,这样 Bloodhound 引擎就可以像预期的那样查找它。

这就是我的 JavaScript 代码现在的样子(HTML 与问题没有变化):

$(document).ready(function () {
    var accounts = new Bloodhound({
        datumTokenizer: Bloodhound.tokenizers.obj.whitespace('Name'),
        queryTokenizer: Bloodhound.tokenizers.whitespace,
        remote: {
            url: "http://****/****/xrmservices/2011/OrganizationData.svc/AccountSet?$select=Name,AccountId&$filter=substringof('%QUERY',Name) and StateCode/Value eq 0",
            filter: function (accounts) {
                return $.map(accounts.d.results, function (account) {
                    return {
                        Name: account.Name,
                        AccountId: account.AccountId
                    };
                });
            }
        }
    });

    accounts.initialize();

    $("#account").typeahead({
        hint: true,
        highlight: true,
        minLength: 2
    }, {
        name: 'account',
        displayKey: 'Name',
        source: accounts.ttAdapter()
    });


    $("#account").on('typeahead:selected', function(dom, selectedItem) {
        console.log(selectedItem.AccountId);
    });
});

希望这能帮助和我做同样事情的其他人:)