Hello,
Je voulais créer une fonction de callback quand mon ng-repeat a terminé sa tâche sur mon tableau.

J'ai donc crée une directive en utilisant la propriété $last du scope local de ng-repeat et cela fonctionne très bien.
https://docs.angularjs.org/api/ng/directive/ngRepeat

.directive('loopEnd', function() {
    return function($scope) {
        if ($scope.$last){
         // Hey bro
        };
    };
})

Sauf que quand je push de nouvelles donées dans mon tableau mon ng-repeat fait son job mais ma directive ne fonctionne plus.
Ma directive ne fonctionne qu'une fois.

6 réponses


je ne sais pas ce que tu veux faire dans cette directive mais je te conseillerai de plutôt le faire dans ton controller avant le rendu HTML.

brokleen
Auteur

Yo, désolé pour la réponse aussi tardive.
Le traitement que je veux faire il doit être fait après le rendu HTML.

@brokleen: Dans l'idée, tu es dans le bon, par contre, dans la logique, tu n'y es pas.

Tu dois bien faire une directive qui va vérifier lorsque tu arrive au dernier élément de ton ng-repeat, sauf que tu ne dois pas déclencher ta fonction à ce moment là.
L'idée est d'emettre un event via scope.$emit('lastElementOfNgRepeat') et dans ton controller tu va ecouter cet event pour déclencher ta fonction.

Pour résumé :

Dans ta directive:

.directive('loopEnd', function() {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last) {
                $timeout(function () {
                    scope.$emit('lastElementOfNgRepeat');
                });
            }
        }
    }
})

Le $timeout est là pour être sur que ce sera executer après que la boucle ai fini.

Dans ton controller:

$scope.$on('lastElementOfNgRepeat', function(event) {
    // Ta fonction.
});

Et dans ton html :

<div ng-repeat="" loop-end="lastElementOfNgRepeat">
</div>

Voilà, j'espere que j'aurais pu t'aider à mieux comprendre comment ça fonctionne.

petite question pour info personel, on ne pourrai pas remplacer le $timeout par un apply vue que $timeout lance un $apply si je dit pas de betise

En effet $timeout fait bien appel à $rootScope.$apply, mais à la différence de $apply, $timeout va attendre que la directive soit initialisée, le scope sera donc défini, ce qui permet d'accéder aux variables et fonctions de ce dernier.

Il y a aussi le soucis que, si tu as un $digest en cours, ton $apply va te retourner une erreur, alors que le $timeout va attendre la fin du cycle du $digest pour se lancer.

Je suis pas un expert, mais c'est un petit résumé. Pour plus de détails je t'invite à lire ceci : http://stackoverflow.com/a/23073968 et http://www.codingeek.com/angularjs/angular-js-apply-timeout-digest-evalasync/.

Oui, c'est foutrement complexe angular :D

brokleen
Auteur

Merci pour ton retour, mes recherches m'avaient donné la solution du $emit.
Mais sans restrict et link, dans le code que j'ai trouvé il ne retourne qu'une fonction avec $scope, $element, $attrs en params

Il me reste une dernière chose que j'aimerais faire, effectuerne opération sur chaque élement avant de retourner l'événément.

Mon idée était d'envoyer le nombre d'élement dans le scope, et dans la directive, grâce à l'index parcouir chaque élément. Quand l'index est égale au nombre d'élement à ce moment-là retourner l'event.