Ich habe ein Leistungsproblem, das ich nicht zu beheben scheine. Ich habe eine sofortige Suche, aber es ist etwas verzögert, da es beginnt die Suche auf jedem keyup()
.
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:searchText">
<span>{{entry.content}}</span>
</div>
Die JSON-Daten ist nicht einmal so groß, nur 300KB, ich denke, was ich erreichen muss, ist eine Verzögerung von ~1 sec auf die Suche zu setzen, um zu warten, bis der Benutzer zu beenden, tippen, anstatt die Aktion auf jedem Tastendruck durchzuführen. AngularJS tut dies intern, und nach dem Lesen von docs und andere Themen auf hier konnte ich nicht finden, eine spezifische Antwort.
Ich würde alle Hinweise auf, wie ich die sofortige Suche verzögern kann zu schätzen wissen.
UPDATE
Jetzt ist es einfacher als je zuvor (Angular 1.3), fügen Sie einfach eine Entprellung Option auf dem Modell.
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
Aktualisierter Plunker: http://plnkr.co/edit/4V13gK
Dokumentation zu ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Alte Methode:
Hier ist eine weitere Methode, die nur von Angular selbst abhängig ist.
Sie müssen eine Zeitüberschreitung festlegen und vergleichen Sie Ihre aktuelle Zeichenfolge mit der vergangenen Version, wenn beide gleich sind dann führt es die Suche.
$scope.$watch('searchStr', function (tmpStr)
{
if (!tmpStr || tmpStr.length == 0)
return 0;
$timeout(function() {
// if searchStr is still the same..
// go ahead and retrieve the data
if (tmpStr === $scope.searchStr)
{
$http.get('//echo.jsontest.com/res/'+ tmpStr).success(function(data) {
// update the textarea
$scope.responseData = data.res;
});
}
}, 1000);
});
und dies geht in Ihre Ansicht:
<input type="text" data-ng-model="searchStr">
<textarea> {{responseData}} </textarea>
Der obligatorische Plunker: http://plnkr.co/dAPmwf
(Siehe Antwort unten für eine Angular 1.3-Lösung).
Das Problem hier ist, dass die Suche jedes Mal ausgeführt wird, wenn das Modell ändert, die jede keyup Aktion auf eine Eingabe ist.
Es gäbe sauberere Wege, dies zu tun, aber wahrscheinlich der einfachste Weg wäre, die Bindung zu wechseln, so dass Sie eine $scope-Eigenschaft innerhalb Ihres Controllers definiert haben, auf die Ihr Filter arbeitet. Auf diese Weise können Sie steuern, wie häufig die $scope-Variable aktualisiert wird. Etwas wie dies:
JS:
var App = angular.module('App', []);
App.controller('DisplayController', function($scope, $http, $timeout) {
$http.get('data.json').then(function(result){
$scope.entries = result.data;
});
// This is what you will bind the filter to
$scope.filterText = '';
// Instantiate these variables outside the watch
var tempFilterText = '',
filterTextTimeout;
$scope.$watch('searchText', function (val) {
if (filterTextTimeout) $timeout.cancel(filterTextTimeout);
tempFilterText = val;
filterTextTimeout = $timeout(function() {
$scope.filterText = tempFilterText;
}, 250); // delay 250 ms
})
});
HTML:
<input id="searchText" type="search" placeholder="live search..." ng-model="searchText" />
<div class="entry" ng-repeat="entry in entries | filter:filterText">
<span>{{entry.content}}</span>
</div>
Entprellte / gedrosselte Modell-Updates für angularjs :
In Ihrem Fall gibt es nichts mehr zu tun, als die Richtlinie in den jsfiddle-Code wie folgt zu verwenden:
<input
id="searchText"
type="search"
placeholder="live search..."
ng-model="searchText"
ng-ampere-debounce
/>
Es handelt sich im Grunde um ein kleines Stück Code, das aus einer einzigen Angular-Direktive namens "ng-ampere-debounce" besteht, die http://benalman.com/projects/jquery-throttle-debounce-plugin/ verwendet und an jedes Dom-Element angehängt werden kann. Die Direktive ordnet die angehängten Event-Handler neu an, so dass sie steuern kann, wann die Ereignisse gedrosselt werden sollen.
Sie können es für die Drosselung/Entprellung verwenden
Werfen Sie einen Blick darauf:
Die Richtlinie wird Teil des Orangevolt Ampere Frameworks (https://github.com/lgersman/jquery.orangevolt-ampere) sein.