Verwendung von Knockout mit Typeahead.js und Bloodhound.js v0.10
-
21-12-2019 - |
Frage
Ich bin gerade dazu übergegangen, Bloodhound.js und Typeahead.js mit Knockout zu verwenden.Ich habe ein paar Probleme –
- Das Typeahead zeigt das nicht an
Name
Eigenschaft in der Vorschlagsliste - Ich kann nicht herausfinden, wie ich den Satz aktualisieren kann, gegen den abgefragt werden soll
Ich füge gerade „statisch“ neue Daten hinzu, aber sie sollten immer noch im Ergebnissatz angezeigt werden, was aber nicht der Fall ist
self.addNew = function () {
self.someOptions.push(new Option(self.someOptions().length + 1, 'Johnnn'));
}
Ich freue mich über Vorschläge, die funktionieren, also bleibe ich nicht bei der Verwendung von Bloodhound.js hängen, wenn es nicht erforderlich ist. Aufgrund der Art meiner App kann ich die Eigenschaften jedoch nicht als Observablen entfernen, der Aufruf von ko.toJS jedoch irgendwann definitiv eine Option.
Lösung
Das erste Problem betrifft den displayKey.Sie müssen in Ihrer Bindung eine explizite Funktion bereitstellen
HTML
<input type="text" data-bind="typeahead: { name: 'something', taOptions: theseOptions, displayKey: 'Name' }, value: thisValue" />
Javascript
// In ko.bindingHandlers.typeahead.init function
var displayKey = options.displayKey;
options.displayKey = function(item) {
return item[displayKey]();
};
Das zweite Problem liegt bei der Verwendung von local.Es sieht so aus, als ob das System die Quelle nach der Initialisierung nicht neu berechnet.Wenn Sie sich die Dokumente ansehen, müssen Sie wahrscheinlich die Remote-Option nutzen und sich als Ajax-Anfrage/Antwort ausgeben.Sie müssen außerdem Ihren eigenen Ergebnisfilter implementieren und bei der Aktualisierung der Optionen einen der beiden requestCache umgehen.
Ich habe deine aktualisiert jsFiddle mit den folgenden...
self.theseOptions = new Bloodhound({
datumTokenizer: function(d) {
var seomth = Bloodhound.tokenizers.whitespace(d.Name());
console.log(seomth);
return seomth },
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote : {
url : '%QUERY',
transport : function(url, options, onSuccess, onError) {
var deferred = $.Deferred();
deferred.done( function() { onSuccess(this); });
var filterVal = url.toLowerCase();
var result = self.someOptions().filter( function(item) {
return !!~item.Name().toLowerCase().indexOf(filterVal);
});
deferred.resolveWith( result );
return deferred.promise();
}
}
//local: self.someOptions()
});
self.addNew = function () {
self.someOptions.push(new Option(self.someOptions().length + 1, 'Johnnn'));
self.theseOptions.transport.constructor.resetCache();
}