De fato, você deve usar diretivas e não há evento vinculado ao final de um loop ng-Repeat (já que cada elemento é construído individualmente e possui seu próprio evento). Mas a) usar diretivas pode ser tudo o que você precisa eb) existem algumas propriedades específicas do ng-Repeat que você pode usar para criar seu evento "no ngRepeat concluído".
Especificamente, se tudo o que você deseja é estilizar / adicionar eventos a toda a tabela, é possível fazê-lo usando uma diretiva que inclua todos os elementos ngRepeat. Por outro lado, se você quiser endereçar cada elemento especificamente, poderá usar uma diretiva dentro do ngRepeat e ela atuará em cada elemento, depois que ele for criado.
Então, há o $index
, $first
, $middle
e $last
propriedades que você pode usar para eventos de disparo. Então, para este HTML:
<div ng-controller="Ctrl" my-main-directive>
<div ng-repeat="thing in things" my-repeat-directive>
thing {{thing}}
</div>
</div>
Você pode usar diretivas assim:
angular.module('myApp', [])
.directive('myRepeatDirective', function() {
return function(scope, element, attrs) {
angular.element(element).css('color','blue');
if (scope.$last){
window.alert("im the last!");
}
};
})
.directive('myMainDirective', function() {
return function(scope, element, attrs) {
angular.element(element).css('border','5px solid red');
};
});
Veja em ação neste Plunker . Espero que ajude!
myMainDirective
o código seja executado somente após o final do loop? Preciso atualizar a barra de rolagem da div pai.Se você simplesmente deseja executar algum código no final do loop, aqui está uma variação um pouco mais simples que não requer manipulação extra de eventos:
Veja uma demonstração ao vivo.
fonte
Não há necessidade de criar uma diretiva, especialmente apenas para ter um
ng-repeat
evento completo.ng-init
faz a mágica para você.isso
$last
garante quefinished
apenas seja acionado quando o último elemento for renderizado no DOM.Não se esqueça de criar
$scope.finished
evento.Feliz codificação !!
Edição: 23 out 2016
Caso você também deseje chamar a
finished
função quando não houver nenhum item na matriz, poderá usar a seguinte solução alternativaBasta adicionar a linha acima na parte superior do
ng-repeat
elemento. Ele verificará se a matriz não está tendo nenhum valor e chamará a função adequadamente.Por exemplo
fonte
Aqui está uma diretiva repetida que chama uma função especificada quando verdadeira. Eu descobri que a função chamada deve usar $ timeout com intervalo = 0 antes de fazer a manipulação do DOM, como inicializar dicas de ferramentas nos elementos renderizados. jsFiddle: http://jsfiddle.net/tQw6w/
Em $ scope.layoutDone, tente comentar a linha $ timeout e descomentar a mensagem "NÃO CORRETO!" linha para ver a diferença nas dicas de ferramentas.
JS:
fonte
Aqui está uma abordagem simples
ng-init
que nem sequer exige uma diretiva personalizada. Funcionou bem para mim em certos cenários, por exemplo, a necessidade de rolar automaticamente uma div de itens repetidos em ng para um item específico no carregamento da página; portanto, a função de rolagem precisa esperar até que ang-repeat
renderização seja concluída no DOM antes que ele possa ser acionado.Observe que isso é útil apenas para funções que você precisa chamar uma vez após o ng-repeat ser processado inicialmente. Se você precisar chamar uma função sempre que o conteúdo de ng-repeat for atualizado, será necessário usar uma das outras respostas nesse segmento com uma diretiva personalizada.
fonte
Complementando a resposta de Pavel , algo mais legível e facilmente compreensível seria:
Por que mais você acha
angular.noop
existe em primeiro lugar ...?Vantagens:
Você não precisa escrever uma diretiva para isso ...
fonte
ng-init="$last && doSomething( )"
Talvez uma abordagem um pouco mais simples com a de
ngInit
Lodashdebounce
método sem a necessidade de diretiva personalizada:Controlador:
Modelo:
Atualizar
Existe ainda mais solução AngularJS pura e simples usando o operador ternário:
Modelo:
Esteja ciente de que o ngInit usa a fase de compilação de pré-link - ou seja, a expressão é invocada antes que as diretivas filhas sejam processadas. Isso significa que ainda pode ser necessário um processamento assíncrono.
fonte
ng-init="$last ? refresh() : false"
também funcionaria. E isso nem exige Lodash.Também pode ser necessário quando você checa a
scope.$last
variável para envolver seu gatilho com asetTimeout(someFn, 0)
. AsetTimeout 0
é uma técnica aceita em javascript e era essencial que eudirective
funcionasse corretamente.fonte
Isso é uma melhoria das idéias expressas em outras respostas para mostrar como obter acesso às propriedades ngRepeat ($ index, $ first, $ middle, $ last, $ even, $ odd) ao usar sintaxe declarativa e isolar escopo ( Prática recomendada pelo Google) com uma diretiva de elemento. Observe a diferença principal:
scope.$parent.$last
.fonte
Eu fiz assim.
Crie a diretiva
Depois de adicioná-lo no rótulo onde esta repetição ng
E pronto com isso será executado no final do ng-repeat.
fonte
Minha solução foi adicionar um div para chamar uma função se o item fosse o último em uma repetição.
fonte
eu gostaria de adicionar outra resposta, já que as respostas anteriores consideram que o código necessário para executar o ngRepeat é um código angular, que nesse caso todas as respostas acima fornecem uma solução ótima e simples, algumas mais genéricas que outras, e caso seja importante o estágio do ciclo de vida do resumo, você pode dar uma olhada no blog de Ben Nadel , com a exceção de usar $ parse em vez de $ eval.
mas na minha experiência, como afirma o OP, geralmente está executando alguns plug-ins ou métodos JQuery no DOM finalmente compilado, que nesse caso eu achei que a solução mais simples é criar uma diretiva com um setTimeout, já que a função setTimeout é pressionada até o final da fila do navegador, é sempre logo depois que tudo é feito em angular, geralmente ngReapet, que continua após a função postLinking dos pais
para quem quer saber que, nesse caso, por que não usar $ timeout, isso causa outro ciclo de digestão que é completamente desnecessário
fonte
Eu tive que renderizar fórmulas usando MathJax após o fim da repetição de ng, nenhuma das respostas acima resolveu meu problema, então fiz como abaixo. Não é uma solução agradável , mas funcionou para mim ...
fonte
Encontrei uma resposta aqui bem praticada, mas ainda era necessário adicionar um atraso
Crie a seguinte diretiva:
Adicione-o ao seu repetidor como um atributo, assim:
De acordo com Radu:
Para mim, funciona, mas ainda preciso adicionar um setTimeout
fonte
Se você simplesmente deseja alterar o nome da classe para que seja renderizado de maneira diferente, o código abaixo faria o truque.
Esse código funcionou para mim quando eu tinha um requisito semelhante para renderizar o item comprado na minha lista de compras na fonte Strick trough.
fonte