Tenho um problema de desempenho que não consigo resolver. Eu tenho uma pesquisa instantânea, mas é um pouco lenta, pois começa a pesquisar em cada uma 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>
Os dados JSON não são tão grandes, apenas 300 KB, acho que o que preciso fazer é colocar um atraso de ~ 1 segundo na pesquisa para aguardar que o usuário termine de digitar, em vez de executar a ação em cada pressionamento de tecla. O AngularJS faz isso internamente e, depois de ler documentos e outros tópicos aqui, não consegui encontrar uma resposta específica.
Agradeço qualquer indicação de como posso atrasar a pesquisa instantânea.
Respostas:
(Veja a resposta abaixo para obter uma solução Angular 1.3.)
O problema aqui é que a pesquisa será executada toda vez que o modelo for alterado, que é toda ação de keyup em uma entrada.
Haveria maneiras mais limpas de fazer isso, mas provavelmente a maneira mais fácil seria alternar a ligação para que você tenha uma propriedade $ scope definida dentro do seu Controller na qual seu filtro opera. Dessa forma, você pode controlar com que frequência a variável $ scope é atualizada. Algo assim:
JS:
HTML:
fonte
ng-model
não vai funcionar dentro de inicialização angular-ui modalATUALIZAR
Agora está mais fácil do que nunca (Angular 1.3), basta adicionar uma opção de rejeição ao modelo.
<input type="text" ng-model="searchStr" ng-model-options="{debounce: 1000}">
Plunker atualizado:
http://plnkr.co/edit/4V13gK
Documentação sobre ngModelOptions:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Método antigo:
Aqui está outro método sem dependências além do próprio angular.
Você precisa definir um tempo limite e comparar sua cadeia atual com a versão anterior, se as duas forem iguais, então ela realiza a pesquisa.
e isso entra na sua visão:
O desentupidor obrigatório: http://plnkr.co/dAPmwf
fonte
No Angular 1.3, eu faria o seguinte:
HTML:
Controlador:
Basicamente, você está dizendo ao angular para executar
myDebouncedFunction()
, quando amsg
variável do escopo muda. O atributong-model-options="{debounce: 1000}"
garante quemsg
somente seja possível atualizar uma vez por segundo.fonte
Agora podemos definir o debounce de ng-model-options com o tempo e, quando desfocado, o modelo precisa ser alterado imediatamente, caso contrário, ao salvar, ele terá um valor mais antigo se o atraso não for concluído.
fonte
Para quem usa keyup / keydown na marcação HTML. Isso não usa relógio.
JS
HTML
fonte
Atualizações de modelo reprovadas / limitadas para angularjs: http://jsfiddle.net/lgersman/vPsGb/3/
No seu caso, não há mais nada a fazer do que usar a diretiva no código jsfiddle assim:
É basicamente um pequeno pedaço de código que consiste em uma única diretiva angular chamada "ng-ampere-debounce" utilizando http://benalman.com/projects/jquery-throttle-debounce-plugin/ que pode ser anexada a qualquer elemento dom. A diretiva reordena os manipuladores de eventos anexados para que possa controlar quando controlar os eventos.
Você pode usá-lo para estrangular / depurar * atualizações angulares do modelo * manipulador de eventos angular ng- [event] * manipuladores de eventos jquery
Dê uma olhada: http://jsfiddle.net/lgersman/vPsGb/3/
A diretiva fará parte da estrutura do Orangevolt Ampere ( https://github.com/lgersman/jquery.orangevolt-ampere ).
fonte
Apenas para usuários redirecionados aqui:
Conforme introduzido,
Angular 1.3
você pode usar o atributo ng-model-options :fonte
Acredito que a melhor maneira de resolver esse problema é usar o plugin jQuery throttle / debounce de Ben Alman . Na minha opinião, não há necessidade de adiar os eventos de todos os campos em seu formulário.
Apenas envolva sua função de manipulação $ scope. $ Watch em $ .debounce da seguinte maneira:
fonte
Outra solução é adicionar uma funcionalidade de atraso ao modelo de atualização. A diretiva simples parece fazer um truque:
Uso:
Então você apenas usa
delayed-model
no lugarng-model
e define o desejadodata-delay
.Demonstração: http://plnkr.co/edit/OmB4C3jtUD2Wjq5kzTSU?p=preview
fonte
model: '=delayedModel'
está funcionando? Ou você pode me indicar um link para encontrá-lo?element.on('change')
dispara apenas no desfoque. (1) Existe uma solução alternativa? (2) como chamar uma função do controlador na alteração de texto?Eu resolvi esse problema com uma diretiva que, basicamente, o que ele faz é vincular o modelo ng real em um atributo especial que assisto na diretiva; em seguida, usando um serviço de debounce, atualizo meu atributo de diretiva, para que o usuário observe a variável que ele vincula ao modelo de rejeição em vez do modelo ng.
Uso:
E no controlador:
Demonstração em jsfiddle: http://jsfiddle.net/6K7Kd/37/
o serviço $ debounce pode ser encontrado aqui: http://jsfiddle.net/Warspawn/6K7Kd/
Inspirado pela diretiva eventualmenteBind http://jsfiddle.net/fctZH/12/
fonte
O Angular 1.3 terá debounce de ng-model-options, mas até então, você precisará usar um timer como Josue Ibarra disse. No entanto, em seu código, ele lança um cronômetro a cada pressionamento de tecla. Além disso, ele está usando setTimeout, quando em Angular é necessário usar $ timeout ou $ apply no final de setTimeout.
fonte
Por que todo mundo quer usar o relógio? Você também pode usar uma função:
fonte
Eu acho que a maneira mais fácil aqui é pré-carregar o json ou carregá-lo uma vez
$dirty
e, em seguida, a pesquisa de filtro cuidará do resto. Isso economiza as chamadas http extras e é muito mais rápido com os dados pré-carregados. A memória vai doer, mas vale a pena.fonte