web-dev-qa-db-fra.com

Rendre la valeur sans liaison de données

Dans AngularJS, comment puis-je restituer une valeur sans liaison de données bidirectionnelle? On peut vouloir le faire pour des raisons de performances, ou même en rendant une valeur à un moment donné.

Les exemples suivants utilisent tous deux la liaison de données:

<div>{{value}}</div>

<div data-ng-bind="value"></div>

Comment rendre valuesans aucune liaison de données?

86
Blowsie

angulaire 1,3 +

En 1.3, Angular a supporté cela en utilisant la syntaxe suivante.

<div>{{::message}}</div>

Comme mentionné dans cette réponse .


angulaire 1.2 et inférieure

C'est simple et ne nécessite pas de plugin. Regarde ça.

Cette petite directive accomplira facilement ce que vous essayez d'atteindre.

app.directive('bindOnce', function() {
    return {
        scope: true,
        link: function( $scope ) {
            setTimeout(function() {
                $scope.$destroy();
            }, 0);
        }
    }
});

Vous pouvez lier une fois comme ça

<div bind-once>I bind once - {{message}}</div>

Vous pouvez lier comme d'habitude

<div ng-bind="message" bind-once></div>

Démo: http://jsfiddle.net/fffnb/

Certains d’entre vous utilisent peut-être angular batarang, et comme indiqué dans les commentaires, si vous utilisez cette directive, l’élément apparaît toujours comme étant contraignant quand il ne l’est pas, je suis sûr que cela a quelque chose à voir avec les classes qui sont attachées à l'élément alors essayez ceci, cela devrait fonctionner (non testé). Faites-moi savoir dans les commentaires si cela a fonctionné pour vous.

app.directive('bindOnce', function() {
    return {
        scope: true,
        link: function( $scope, $element ) {
            setTimeout(function() {
                $scope.$destroy();
                $element.removeClass('ng-binding ng-scope');
            }, 0);
        }
    }
});

@ x0b : Si vous avez OCD et que vous voulez supprimer l'attribut vide class faites ceci

!$element.attr('class') && $element.removeAttr('class')
141
iConnor

Il semble que Angular 1.3 (à partir de la version bêta 10) a une liaison unique intégrée dans:

https://docs.angularjs.org/guide/expression#one-time-binding

Reliure ponctuelle

Une expression commençant par :: est considérée comme une expression unique. Les expressions uniques arrêtent de recalculer une fois qu'elles sont stables, ce qui se produit après le premier condensé si le résultat de l'expression est une valeur non indéfinie (voir l'algorithme de stabilisation des valeurs ci-dessous).

49
Karen Zilles

Utilisez le module de bindonce . Vous devez inclure le fichier JS et l'ajouter en tant que dépendance à votre module d'application:

var myApp = angular.module("myApp", ['pasvaz.bindonce']);

Cette bibliothèque vous permet de rendre les éléments liés une seule fois - lors de leur première initialisation. Toute mise à jour ultérieure de ces valeurs sera ignorée. C'est un excellent moyen de réduire le nombre de contrôles sur la page pour les éléments qui ne changeront pas après leur rendu.

Exemple d'utilisation:

<div bo-text="value"></div>

Lorsqu'il est utilisé comme ceci, la propriété sous value sera définie une fois qu'elle sera disponible, mais la montre sera alors désactivée.

20
OverZealous

Comparaison entre les réponses @OverZealous et @Connor:

Avec le ngRepeat traditionnel de angular: 15s pour 2000 lignes et 420mo de RAM ( Plunker )

Avec ngRepeat et le module de @OverZealous: 7s pour 2000 lignes et 240mo de RAM ( Plunker )

Avec ngRepeat et la directive de @Connor: 8s pour 2000 lignes et 500mo de RAM ( Plunker )

J'ai fait mes tests avec Google Chrome 32.

7
Gabriel

Comme alternative, il y a angular-once paquet:

Si vous utilisez AngularJS, avez des problèmes de performances et devez afficher de nombreuses données en lecture seule, ce projet est fait pour vous!

angular-once _ a été inspiré par bindonce et fournit un résultat similaire once-* les attributs:

<ul>
    <li ng-repeat="user in users">
      <a once-href="user.profileUrl" once-text="user.name"></a>
        <a once-href="user.profileUrl"><img once-src="user.avatarUrl"></a>
        <div once-class="{'formatted': user.description}" once-bind="user.description"></div>
    </li>
</ul>
5
alecxe