[javascript] Conditional logic in AngularJS template

I have an angular template which looks like this...

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

I have set up a JSfiddle to show the data being bound.

What I need to do is make the "from", "to" and "arrowTo" divs show conditionally, depending on the content of the data.

The log is is this...

  • If there is a "from" object in the data then show the "from" div and bind the data but don't show the "createdBy" div .
  • If there is no "from" object but there is a "createdBy" object then show the "createdBy" div and bind the data.
  • If there is a "to" object in the data then show the "arrowTo" div and bind it's data.

Or in plain English, if there is a from address, show it, otherwise show who created the record instead and if there is a to address then show that too.

I have looked into using ng-switch but I think I'd have to add extra markup which would leave an empty div if there was no data. Plus I'd need to nest switch directives and I'm not sure if that would work.

Any ideas?

UPDATE:

If I were to write my own directive (If I knew how!) then here is some pseudo code to show how I would want to use it...

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

Each of these would disappear if the function/expression evaluated to false.

This question is related to javascript angularjs

The answer is


You could use the 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>

If you don't want the DOM to be loaded with empty divs, you need to create your custom directive using $http to load the (sub)templates and $compile to inject it in the DOM when a certain condition has reached.

This is just an (untested) example. It can and should be optimized:

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

You can use ng-show on every div element in the loop. Is this what you've wanted: http://jsfiddle.net/pGwRu/2/ ?

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