Comment unwatch " une expression
Dire que j'ai une ng-repeat avec un grand tableau.
Lorsque ng-repeat s'exécute, il ajoute chaque élément de ce tableau pour un isolé champ d'application, ainsi que le tableau lui-même dans un champ. Cela signifie que $digest vérifie l'ensemble de la matrice pour des changements, et en plus de cela, il vérifie chaque élément individuel dans ce tableau pour les changements.
Voir cette plunker comme un exemple de ce dont je parle.
Dans mon cas d'utilisation, je n'ai jamais changer un seul élément de mon tableau donc je n'ai pas besoin de les avoir vu. Je ne jamais changer l'ensemble de la matrice, dans lequel cas ng-repeat re-rendre le tableau dans son intégralité. (Si je me trompe sur cette s'il vous plaît laissez-moi savoir..)
Dans un tableau de (disons) de 1000 lignes, c'est plus de 1000 expressions que je n'ai pas besoin évalué.
Comment puis-je radier chaque élément de l'observateur tout en continuant à regarder le tableau principal?
Peut-être lieu de retrait de l'enregistrement j'ai pu avoir plus de contrôle sur mon $digest et en quelque sorte sauter chaque ligne individuelle?
Ce cas précis est en fait un exemple d'une question plus générale. Je sais que $watch retourne un 'deregisteration fonction, mais ça n'aide pas lorsqu'une directive est en cours d'enregistrement les montres, ce qui est la plupart du temps.
Vous devez vous connecter pour publier un commentaire.
Avoir un répéteur avec un grand tableau que vous ne regardez pas de regarder chaque élément.
Vous aurez besoin de créer un personnalisé directive qui prend un argument, et l'expression de votre tableau, puis dans la fonction de liaison de vous venais de regarder ce tableau, et vous auriez la fonction de liaison par programme actualiser le code HTML (plutôt que d'utiliser un ng-repeat)
quelque chose comme (pseudo-code):
... ce qui semble être une douleur dans le cul.
Suppléant hackish méthode
Vous pourriez être en mesure de faire une boucle par
$scope.$$watchers
et d'examiner$scope.$$watchers[0].exp.exp
pour voir si elle correspond à l'expression que vous souhaitez supprimer, puis l'enlever avec un simplesplice()
appel. La PITA ici, c'est que des choses commeBlah {{whatever}} Blah
entre les balises seront l'expression, et même inclure des retours chariot.À la hausse, vous pourriez être en mesure de simplement faire une boucle par le $portée de votre ng-repeat et d'effacer tout, puis ajouter explicitement la montre que vous voulez... je ne sais pas.
De toute façon, il semble comme un hack.
Pour supprimer un observateur faite par $scope.$regarder
Vous pouvez annuler l'inscription d'un
$watch
avec la fonction renvoyée par le$watch
appel:Par exemple, pour avoir un
$watch
déclencher une seule fois:Vous pouvez, bien sûr, appelez la fonction désinscription à tout moment vous voulez... c'était juste un exemple.
Conclusion: Il n'y a pas vraiment une bonne façon de faire exactement ce que vous demandez
Mais une chose à considérer: Est-il même la peine de s'inquiéter à propos de? Par ailleurs est-ce vraiment une bonne idée d'avoir des milliers de documents chargés dans des dizaines de DOMElements chaque? De la nourriture pour la pensée.
J'espère que ça aide.
EDIT 2 (supprimé mauvaise idée)
$watch retourne une fonction qui délie l' $regarder lorsqu'il est appelé. Donc, ce est tout ce dont vous avez besoin pour "watchOnce":
Edit: voir la réponse que j'ai posté.
J'ai fait et mis en œuvre blesh l'idée dans un seperable façon. Mon
ngOnce
directive simplement détruit l'enfant quingRepeat
crée sur chaque élément. Cela signifie que le champ d'application n'a pas obtenir de l'atteinte de ses parentsscope.$digest
et les observateurs ne sont jamais exécutées.Source et exemple sur JSFiddle
La directive elle-même:
De l'utiliser:
Note
ng-once
ne pas créer son propre champ qui signifie qu'il peut affecter les éléments frères. Ces tous la même chose:Note cela peut être une mauvaise idée
Vous pouvez ajouter la
bindonce
directive à votreng-repeat
. Vous aurez besoin de télécharger à partir de https://github.com/pasvaz/bindonce.modifier: quelques mises en garde:
Si vous utilisez
{{}}
interpolation dans votre modèle, vous devez le remplacer avec<span bo-text>
.Si vous utilisez
ng-
directives, vous devez les remplacer avec le droitbo-
directives.Aussi, si vous êtes à la mise
bindonce
etng-repeat
sur le même élément, vous devriez essayer de déplacer labindonce
à un élément parent (voir https://github.com/Pasvaz/bindonce/issues/25#issuecomment-25457970 ) ou en ajoutant destrack by
à votreng-repeat
.Si vous utilisez
angularjs 1.3
ou au-dessus, vous pouvez utiliser le seul lier syntaxe queCela aura pour effet de lier la valeur et va supprimer les observateurs, une fois la première digérer cycle est exécuté et la modification de la valeur de
undefined
àdefined
pour la première fois.Très utile BLOG sur ce.