10

Basically, I have this code in my template:

<tr ng-repeat="entry in tableEntries">

  <td ng-switch="entry.url == ''">
    <span ng-switch-when="false"><a href="{{entry.url}}">{{entry.school}}</a></span>
    <span ng-switch-when="true">{{entry.school}}</span>
  </td>

  ...
</tr>

As you can see I'm trying to display a clickable URL when entry.url is not empty and a plain text otherwise. It works fine, but it looks quite ugly. Is there a more elegant solution?

Another way I can think of doing it is using ng-if:

<td>
  <span ng-if="entry.url != ''"><a href="{{entry.url}}">{{entry.school}}</a></span>
  <span ng-if="entry.url == ''">{{entry.school}}</span>
</td>

But then I would be repeating almost the same comparison twice, which looks even worse. How would you guys approach this?

Rahil Wazir
  • 10,007
  • 11
  • 42
  • 64
Victor Marchuk
  • 13,045
  • 12
  • 43
  • 67

4 Answers4

6

You can try.

<div ng-show="!link">hello</div> <div ng-show="!!link"><a href="{{link}}">hello</a></div>

But the ngSwitch which you are using should be fine.

N.Venkatesh Naik
  • 124
  • 1
  • 1
  • 10
2

Use double negation, it cast into boolean thus !!entry.url will return true if string is not empty.

<td ng-switch="!!entry.url">
    <span ng-switch-when="true"><a href="{{entry.url}}">{{entry.school}}</a></span>
    <span ng-switch-when="false">{{entry.school}}</span>
</td>

A good read What is the !! (not not) operator in JavaScript? and Double negation (!!) in javascript - what is the purpose?

Community
  • 1
  • 1
Satpal
  • 132,252
  • 13
  • 159
  • 168
2

You can create a custom directive that hides the complexity:

HTML

<tr ng-repeat="entry in tableEntries">
  <td>
    <link model="entry"></link>
  </td>
  ...
</tr>

JS

app.directive('link', function() {
    return  {
        restrict: 'E', 
        scope: {
           model: '='
        },
        template: '<a ng-if="model.url != ''" href="{{model.url}}">{{model.school}}</a><span ng-if="model.url == ''"> {{ model.school }}</span>'

    }
});
Michael Kang
  • 52,003
  • 16
  • 103
  • 135
-2

I would recommend having an ng-class="{'className': whenEntryURLisWhatever}" in your td, and make it change the css styles accessed, e.g:

td span{ /*#normal styles#*/ }
.className span{ /*#styles in the case of added classname (when it is a link)#*/
           text-decoration: underline; 
           cursor:   pointer; 
}

Then just change what happens on ng-click within a function defined in your javascript code.

$scope.yourFunction = function(url){
    if(!!url){
        window.location = YourURL;
    }
}

This would cut down on code repetition, as your html could now be:

 <tr ng-repeat="entry in tableEntries">
  <td ng-class="{'className': !!entry.url}">
    <span ng-click="yourFunction(entry.url)">{{entry.school}}</span> 
  </td>
  ...
</tr>
  • What ng-click? I have no idea what you are talking about. Do you suggest hiding unused elements in CSS? How is it any better than what I'm doing now? – Victor Marchuk Jan 02 '15 at 11:12
  • not at all, in your css you can have `.className span{ text-decoration: underline; cursor: pointer; }` and any other styles you want on a link. Then inside your span, have `ng-click="yourFunction()"` – Michal Paszkiewicz Jan 02 '15 at 11:19
  • I have edited the answer to try and explain this better. – Michal Paszkiewicz Jan 02 '15 at 11:27