69 votes

Logique conditionnelle dans le modèle AngularJS

J'ai angulaire modèle qui ressemble à ceci...

<div ng-repeat="message in data.messages" ng-class="message.type">

    <div class="info">
        <div class="type"></div>
        <div class="from">From Avatar</div>
        <div class="createdBy">Created By Avatar</div>
        <div class="arrowTo">
            <div class="arrow"></div>
            <div class="to">To Avatar</div>
        </div>
        <div class="date">
            <div class="day">25</div>
            <div class="month">Dec</div>
        </div>
    </div>

    <div class="main">
        <div class="content">
            <div class="heading2">{{message.title}}</div>
            <div ng-bind-html="message.content"></div>
        </div>

    </div>

    <br />
    <hr />
    <br />

</div>

J'ai mis en place un JSfiddle pour afficher les données lié.

Ce que je dois faire, c'est de faire le "de", "à" et "arrowTo" divs montrer, sous certaines conditions, en fonction du contenu des données.

Le journal est c'est...

  • Si il y a un "de" dans l'objet de données, puis de montrer la "" de la div et la liaison de données, mais ne montrent pas le "createdBy" div .
  • Si il n'y a pas de "partir" de l'objet, mais il y a un "createdBy" objet de montrer ensuite la "createdBy" div et la liaison de données.
  • Si il y a un "objet" dans les données, puis les "arrowTo" div et de lier des données.

Ou en clair, si il y a une adresse de le montrer, sinon de montrer qui a créé la notice, au lieu et s'il est à l'adresse de montrer ensuite que trop.

J'ai regardé dans l'aide de ng-switch, mais je pense que j'aurais à ajouter de balisage qui laisserait une div vide si il n'y a pas de données. En Plus, j'avais besoin d'nid commutateur directives et je ne suis pas sûr que ça marcherait.

Des idées?

Mise à JOUR:

Si je devais écrire mon propre directive (Si je savais comment faire!) alors voici le pseudo-code pour montrer comment j'ai envie de l'utiliser...

<div ng-if="showFrom()">
    From Template Goes Here
</div>
<div ng-if="showCreatedBy()">
    CreatedBy Template Goes Here
</div>
<div ng-if="showTo()">
    To Template Goes Here
</div>

Chacun de ces disparaîtrait si la fonction/expression évaluée à false.

88voto

Mark Rajcok Points 85912

Angulaire 1.1.5 introduit la ng-si la directive. C'est la meilleure solution pour ce problème particulier. Si vous utilisez une ancienne version de Anguleuses, pensez à utiliser angular-ui ui-si la directive.

Si vous êtes arrivé ici, à la recherche de réponses à la question plus générale de la "logique conditionnelle dans les modèles" aussi considérer:


Réponse originale à cette question:

Voici un pas-si-grand "ng-si" directive:

myApp.directive('ngIf', function() {
    return {
        link: function(scope, element, attrs) {
            if(scope.$eval(attrs.ngIf)) {
                // remove '<div ng-if...></div>'
                element.replaceWith(element.children())
            } else {
                element.replaceWith(' ')
            }
        }
    }
});

que permet cette syntaxe HTML:

<div ng-repeat="message in data.messages" ng-class="message.type">
   <hr>
   <div ng-if="showFrom(message)">
       <div>From: {{message.from.name}}</div>
   </div>    
   <div ng-if="showCreatedBy(message)">
      <div>Created by: {{message.createdBy.name}}</div>
   </div>    
   <div ng-if="showTo(message)">
      <div>To: {{message.to.name}}</div>
   </div>    
</div>

Le violon.

remplaceavec() est utilisée pour supprimer le contenu inutile de le DOM.

Aussi, comme je l'ai mentionné sur Google+, ng-style peut probablement être utilisé pour conditionnellement charger les images d'arrière-plan, si vous souhaitez utiliser ng-show à la place de la coutume de la directive. (Pour les autres lecteurs, Jon a déclaré sur Google+: "les deux méthodes utilisent ng-show qui j'essaie d'éviter, car il utilise display:none et des feuilles supplémentaires de balisage dans les DOM. C'est un problème particulier dans ce scénario parce que l'élément masqué aura une image de fond qui sera toujours chargé dans la plupart des navigateurs.").
Voir aussi Comment puis-je conditionnellement appliquer des styles CSS en AngularJS?

Le angular-ui ui-si la directive montres pour les changements de la condition if/expression. La mienne n'a pas. Ainsi, alors que mon simple mise en œuvre sera mise à jour de l'afficher correctement si les changements de modèle tel qu'il ne touche que le modèle de sortie, il ne sera pas de mise à jour de l'afficher correctement si les conditions d'expression de la réponse change.

E. g., si la valeur de un de.les changements de nom dans le modèle, la vue de mise à jour. Mais si vous delete $scope.data.messages[0].from, le nom sera retiré de la vue, mais le modèle ne sera pas supprimé de la vue parce que la si-l'état/de l'expression n'est pas surveillé.

19voto

asgoth Points 14599

Vous pouvez utiliser le ngSwitch directive:

  <div ng-switch on="selection" >
    <div ng-switch-when="settings">Settings Div</div>
    <span ng-switch-when="home">Home Span</span>
    <span ng-switch-default>default</span>
  </div>

Si vous ne voulez pas que le DOM est chargé avec vide vrd, vous avez besoin pour créer votre custom directive à l'aide de $http charger le (sous -) modèles et $compiler pour l'injecter dans les DOM lorsqu'une certaine condition a atteint.

C'est juste une (non testé) exemple. Elle peut et doit être optimisé:

HTML:

<conditional-template ng-model="element" template-url1="path/to/partial1" template-url2="path/to/partial2"></div>

Directive:

app.directive('conditionalTemplate', function($http, $compile) {
   return {
      restrict: 'E',
      require: '^ngModel',
      link: function(sope, element, attrs, ctrl) {
        // get template with $http
        // check model via ctrl.$viewValue
        // compile with $compile
        // replace element with element.replaceWith()
      }
   };
});

6voto

matko.kvesic Points 173

Vous pouvez utiliser ng-show sur chaque élément div de la boucle. Est-ce ce que vous vouliez: http://jsfiddle.net/pGwRu/2/ ?

 <div class="from" ng-show="message.from">From: {{message.from.name}}</div>
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X