问题
If one uses Bloodhound with GET:
// Typeahead
personsBloodhound = new Bloodhound({
datumTokenizer: function (person) { return person.name; },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/ajax/Persons/List?nameContains=%QUERY',
ajax: {
beforeSend: function(xhr) {
$(".searching-person").show();
},
data: {
"pageSize": 4,
"otherParam1": "blah",
"otherParam2": "bleh",
}
},
filter: function (response) {
$(".searching-person").hide();
return response.persons;
}
}
});
One simply uses %QUERY in the URL.
Now....
If one uses Bloodhound with POST, what should I use instead of %QUERY?
// Typeahead
personsBloodhound = new Bloodhound({
datumTokenizer: function (person) { return person.name; },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: '/ajax/Persons/List',
ajax: {
type: "POST",
beforeSend: function(xhr) {
$(".searching-person").show();
},
data: {
"nameContains": ....WHAT GOES HERE?????......
"pageSize": 4,
"otherParam1": "blah",
"otherParam2": "bleh",
}
},
filter: function (response) {
$(".searching-person").hide();
return response.persons;
}
}
});
If it was not clear, the question is:
What is the equivalent of %QUERY
when using POST within Bloodhound's remote?
The documentation isn't clear about this, (proof): https://github.com/twitter/typeahead.js/blob/master/doc/bloodhound.md#remote
Also tried using:
"nameContains": $("#my-input-that-uses-typeahead").val(),
But didn't work.
回答1:
You have to alter the URL somehow, otherwise the bloodhound wont send an other request (see https://stackoverflow.com/a/24025789/2175370) and livesearch/typeahead wont work.
So ("#my-input-that-uses-typeahead").val()
works just fine in combination with a dynamic URL (e.g.http://127.0.0.1:1234/REST_API/_search?useless=%QUERY
) and a beforeSend
-function in the ajax setttings.
I gonna file an issue about this behaviour. Using the bloodhound for POST-requests ist VERY awkward and takes away the simplicity intended with typeahead.js.
EDIT:
Also make sure you set the new value for the data in beforeSend
and set settings.hasContent = true
. Otherwise the initial data will be used.
Example on how it's done: https://github.com/twitter/typeahead.js/issues/542#issuecomment-29995960.
回答2:
Right, after further looking at bloodhound the wildcard is just what to replace not the value.
It doesn't store the query string anywhere. On queryChanged
fires and filters remote response. Looks like you'll have to get the query yourself.
"nameContains": $('input#search').val()
回答3:
Equivalent of %QUERY
when using POST within Bloodhound's remote is query
.
Here is a simple example (with detailed explanation) where you can use it for both GET
and POST
. As you can see I have declared a variable isExtendUrl
. If this is set to true
then the query (what you type) will be added to the end of the url (you have to give the myurl
somehow).
The next variable is isRequestMethod
. If this is set to POST
, you can use bloodhound for POST
calls else you can use it for GET
calls. As you can see prepare
function has two parameters query
and setting
. query
is the one what you type. If you just want the POST
call without GET
move prepare
key value pair inside remote
object.
So, if you have to use JSON
body as {gender: 'MALE', name: 'what is typed'}
for your POST
call. You can have an initial query object with all your key value pairs eg: initialQuery = {gender: 'MALE'}
, and the key searchKey
which should be added to initialQuery
when searching, could be added on prepare
like initialQuery[searchKey] = query
.
Finally, if the response object of your POST
call is an object and you have to extract a specific key value use filter
. Eg: Say your response object is
{
status: 'some status',
content: [{array}, {of}, {objects}, ...],
someKey: someValue
}
and you have to get content
, then return data.content
. Here is a full example
let isExtendUrl = true; //to add query at the end of the url, usually used with GET
let isRequestMethod = 'POST';
let initialQuery = {gender: 'MALE'};
let searchKey = 'name';
let bloodhound = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: isExtendUrl ? myurl + '%QUERY' : myurl,
wildcard: '%QUERY',
filter: function (data) {
return $.map(data.content, function (obj) {
return obj;
});
}
}
});
if (isRequestMethod == 'POST') {
let prepare = function (query, settings) {
initialQuery[searchKey] = query;
settings.type = "POST";
settings.contentType = "application/json; charset=UTF-8";
settings.data = JSON.stringify(initialQuery);
return settings;
}
bloodhound.remote.prepare = prepare;
}
来源:https://stackoverflow.com/questions/24108519/twitters-typeahead-bloodhound-what-is-the-equivalent-of-query-when-using-aj