Logique conditionnelle dans le modèle AngularJS

j'ai un gabarit angulaire 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 montrer les données étant liées.

ce que je dois faire est de faire les divs" de"," à "et" arrowTo " montrent conditionnellement, en fonction du contenu des données.

le log est celui-ci...

  • S'il y a un objet" from "dans les données, alors afficher le div" from " et liez les données mais ne montrez pas la div" createdBy".
  • S'il n'y a pas d'objet" from "mais qu'il y a un objet" createdBy", alors montrez le div" createdBy " et liez les données.
  • S'il y a un objet" to "dans les données, alors montrez le div" arrowTo " et liez ses données.

Ou en anglais, 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'utilisation ng-switch mais je pense que je devrais ajouter un supplément qui laisserait une div vide s'il n'y avait pas de données. En plus, j'aurais besoin de changer les directives et je ne suis pas sûr que ça marcherait.

des idées?

mise à jour:

si je devais écrire ma propre directive (Si je savais comment!) alors voici un pseudo code pour montrer comment je voudrais 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 ceux-ci disparaîtrait si la fonction/expression évaluée à false.

66
demandé sur MarioDS 2012-12-29 04:22:00

3 réponses

Angulaire 1.1.5 a introduit le ng-si de la directive. C'est la meilleure solution pour ce problème particulier. Si vous utilisez une ancienne version D'Angular, envisagez d'utiliser angular-ui ui-if directive.

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


réponse originale:

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(' ')
            }
        }
    }
});

qui 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>

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 charger conditionnellement des images d'arrière-plan, si vous voulez utiliser ng-show au lieu d'une directive personnalisée. (Pour le bénéfice des autres lecteurs, Jon a déclaré sur Google+: "les deux méthodes utilisent ng-show que j'essaie d'éviter parce qu'il utilise display:none et laisse un markup supplémentaire dans le 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 directive montres pour les changements de la condition if/expression. La mienne n'a pas. Ainsi, alors que mon la mise en œuvre simple mettra à jour la vue correctement si le modèle change de telle sorte qu'il affecte seulement la sortie du modèle, il ne mettra pas à jour la vue correctement si la condition/réponse d'expression change.

par exemple, si la valeur d'un de.changement de nom dans le modèle, la vue sera mise à jour. Mais si vous delete $scope.data.messages[0].from , le nom de from sera supprimé de la vue, mais le modèle ne sera pas supprimé de la vue parce que la condition/expression if n'est pas observée.

86
répondu Mark Rajcok 2017-05-23 11:46:08

vous pouvez utiliser la 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 soit chargé avec des divs vides, vous devez créer votre directive personnalisée en utilisant $http pour charger les modèles (sub)et $compiler pour l'injecter dans le DOM lorsqu'une certaine condition est atteinte.

ce n'est qu'un exemple (non testé). Il 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()
      }
   };
});
20
répondu asgoth 2012-12-29 16:42:39

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

<div class="from" ng-show="message.from">From: {{message.from.name}}</div>
6
répondu matko.kvesic 2012-12-29 00:42:08