“Live search” może być bardzo ciekawym rozwiązaniem w aplikacji. Użytkownik pisze literki w textboxiku i bez wciskania entera czy guzika dostaje przefiltrowane wyniki. Tak jak to znamy z gógla chociażby.
Jeśli jednak reagować będziemy na każdą zmianę, to zanim użytkownik dostanie wynik zapytania “gdzie się podziały pieniądze z OFE” – wykonamy bardzo wiele zapytań. W takich przypadkach warto puszczać faktycznie zapytanie dopiero gdy nasz szukacz zaprzestanie pisania, czyli na przykład nie zmieni żadnej literki przez pół sekundy.
W angularze można to osiągnąć prawdopodobnie na wiele sposobów. Ja sięgnąłem po mechanizm dyrektyw i napisałem swoją, której wykorzystanie w kodzie wygląda tak:
<input obj="myFilter" delay="500" />
A sama dyrektywa:
.directive('delay', ['$timeout', function ($timeout) { return { restrict: 'A', scope: { obj: '=' }, link: function (scope, element, attrs) { var delay = attrs.delay; if (isNaN(parseInt(delay, 10))) { throw "Delay value in milliseconds must be defined"; } scope.$watch('obj', function (newValue) { element.val(newValue); }); var currentTimeout; element.keyup(function () { $timeout.cancel(currentTimeout); currentTimeout = $timeout(function () { scope.obj = element.val(); }, delay); }); } }; }])
Nice.
w knockout jest to dostępne od razu, więc ciężko mi uwierzyć, że Angular nie ma takiej metody
Knockout ma rateLimit i jeszcez jedną (która od 3 jest deprecated)
Nilphilus,
Może i jest (chociaż nie widzę / nie znalazłem). Ale to jest nieważne, bo jak zaczął się bawić angularem to się okazało że bardzo wiele rzeczy po prostu nie potrzebuje “wbudowanych” odpowiedników bo:
a) łatwo jest je dopisać w elegancki sposób
b) pisanie tego to świetna frajda :)
A nie lepiej w funkcji wykonywanej na callback po prostu robić wywołanie z $timeout i ew. przed wywołaniem zablokować wcześniej ustawiony timeout?
Druga wersja, dodać dyrektywę zapisującą timeout dla konkretnych callbacków i napisać dyrektywy z których korzystamy tak, aby potrafiły zrobićttimeout trochę za naszymi plecami?
Gdy potrzebuję zrobić coś z opóźnieniem, zwykle robie to właśnie wewnątrz callbacku, bez tworzenia osobnej dyrektywy na to.
Nie mogę wykombinować innej rzeczy, jak przypisać model do selecta czy inputa już w runtime, z poziomu kontrolera.
jest, ale jest to po prostu brzydkie w knockout:
this.myFilter = ko.observable().extend({
rateLimit: 500
});
:)
@Gutek jak to brzydkie? ;->