У меня проблема с производительностью, которую я не могу решить. У меня есть мгновенный поиск, но он несколько запаздывает, так как он начинает поиск по каждому 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>
Данные JSON даже не такие большие, всего 300 КБ. Думаю, мне нужно сделать так, чтобы при поиске была задержана ~ 1 секунда, чтобы дождаться, пока пользователь закончит ввод, вместо того, чтобы выполнять действие при каждом нажатии клавиши. AngularJS делает это внутренне, и после прочтения документации и других тем здесь я не смог найти конкретный ответ.
Буду признателен за любые указания о том, как я могу отложить мгновенный поиск.
Ответы:
(См. Ответ ниже для углового решения 1.3.)
Проблема здесь в том, что поиск будет выполняться каждый раз, когда изменяется модель, что является каждым действием keyup на входе.
Были бы более чистые способы сделать это, но, вероятно, самый простой способ - это переключить привязку, чтобы у вас было свойство $ scope, определенное внутри вашего контроллера, на котором работает ваш фильтр. Таким образом, вы можете контролировать частоту обновления переменной $ scope. Что-то вроде этого:
JS:
HTML:
источник
ng-model
не работает в модале начальной загрузки angular-uiОБНОВИТЬ
Теперь это проще, чем когда-либо (Angular 1.3), просто добавьте опцию debounce в модель.
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
Обновленный плункер:
http://plnkr.co/edit/4V13gK
Документация по ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Старый метод:
Вот еще один метод без зависимостей, кроме самого углового.
Вам нужно установить таймаут и сравнить текущую строку с прошлой версией, если обе они одинаковы, тогда он выполняет поиск.
и это идет на ваш взгляд:
Обязательный плункер: http://plnkr.co/dAPmwf
источник
В Angular 1.3 я бы сделал это:
HTML:
контроллер:
По сути, вы говорите angular для запуска
myDebouncedFunction()
, когдаmsg
изменяется переменная области видимости. Атрибутng-model-options="{debounce: 1000}"
гарантирует, чтоmsg
может обновляться только раз в секунду.источник
Теперь мы можем установить отклонение ng-model-options со временем, и когда размытие, модель должна быть немедленно изменена, иначе при сохранении она будет иметь более старое значение, если задержка не будет завершена.
источник
Для тех, кто использует keyup / keydown в разметке HTML. Это не использует часы.
JS
HTML
источник
Отмененные / ограниченные обновления моделей для angularjs: http://jsfiddle.net/lgersman/vPsGb/3/
В вашем случае ничего больше не нужно делать, как использовать директиву в коде jsfiddle следующим образом:
В основном это небольшой фрагмент кода, состоящий из единственной угловой директивы под названием «ng-ampere-debounce», использующей http://benalman.com/projects/jquery-throttle-debounce-plugin/, которая может быть присоединена к любому элементу dom. Директива переупорядочивает подключенные обработчики событий, так что она может контролировать, когда регулировать события.
Вы можете использовать его для регулирования / отклонения * угловых обновлений модели * обработчика угловых событий ng- [event] * обработчиков событий jquery
Посмотрите: http://jsfiddle.net/lgersman/vPsGb/3/
Директива будет частью структуры Orangevolt Ampere ( https://github.com/lgersman/jquery.orangevolt-ampere ).
источник
Просто для пользователей, перенаправленных сюда:
Как было показано,
Angular 1.3
вы можете использовать атрибут ng-model-options :источник
Я считаю, что лучший способ решить эту проблему - использовать плагин Бен Алмана jQuery throttle / debounce . На мой взгляд, нет необходимости откладывать события каждого поля в вашей форме.
Просто оберните вашу функцию обработки $ scope. $ Watch в $ .debounce следующим образом:
источник
Другое решение - добавить функцию задержки в обновление модели. Простая директива, кажется, делает трюк:
Использование:
Таким образом, вы просто используете
delayed-model
вместоng-model
и определить желаемоеdata-delay
.Демонстрация: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p=preview
источник
model: '=delayedModel'
работает? Или вы можете указать мне ссылку, где я могу найти его?element.on('change')
срабатывает только на размытие. (1) Есть ли обход? (2) как вызвать функцию контроллера при изменении текста?Я решил эту проблему с помощью директивы, которая в основном связывает реальную ng-модель со специальным атрибутом, который я наблюдаю в директиве, а затем с помощью службы debounce обновляю свой атрибут директивы, чтобы пользователь наблюдал за переменной, которая он привязывается к debounce-модели вместо ng-модели.
Использование:
И в контроллере:
Демонстрация в jsfiddle: http://jsfiddle.net/6K7Kd/37/
Сервис $ debounce можно найти здесь: http://jsfiddle.net/Warspawn/6K7Kd/
Вдохновлен в конечном итоге директивой Bind http://jsfiddle.net/fctZH/12/
источник
В Angular 1.3 будет отладка ng-model-options, но до тех пор вы должны использовать таймер, как сказал Josue Ibarra. Однако в своем коде он запускает таймер при каждом нажатии клавиши. Также он использует setTimeout, когда в Angular нужно использовать $ timeout или использовать $ apply в конце setTimeout.
источник
Почему все хотят использовать часы? Вы также можете использовать функцию:
источник
Я думаю, что самый простой способ здесь - это предварительно загрузить JSON или загрузить его один раз,
$dirty
и тогда поиск фильтра позаботится обо всем остальном. Это сэкономит вам лишние http-звонки и будет намного быстрее с предварительно загруженными данными. Память повредит, но оно того стоит.источник