Search code examples
javascriptangularjshtml-listsangular-ng-if

How to DRY up list in angular


This is my first time posting a question on stackoverflow so sorry if its not in the correct format.

I keep running into the same problem in angular and i'm sure there is a very simple way to solve it but for some reason i can't figure it out. I will post an example and give an explanation below.

<div class="jmc-navbar-content" ng-if="!vm.isHidden" ng-swipe-up="vm.toggleNav()">
<!-- contains the navigation/page links -->
<ul class="jmc-navbar-menu">
  <li class="active"><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="#home">Home</a></li>
  <li><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="#portfolio">Portfolio</a></li>
  <li><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="#about">About</a></li>
  <li><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="#contact">Contact</a></li>
  <li><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="#/">View source on GitHub</a></li>
</ul>
</div>

Although this works i don't like having to repeat myself for all the <a> tags which need to have the same classes and attributes. I can think of multiple ways in which to do this with javascript but they all seem a little 'hack-y'. Is there any simple way to do this in Angular or Javascript?

Thanks for taking the time to reply, any and all constructive criticism is appreciated.


Solution

  • First you could create an array of objects with the paths and the placeholder(display):

    Then you can use ngRepeat directive:

    <li ng-class="{ 'active': $first }" ng-repeat="link in vm.links"><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="{{link.path}}">{{link.display}}</a></li>
    

    See it working:

    (function() {
      'use strict';
      
      angular
        .module("app", [])
        .controller('MainCtrl', MainCtrl);
    
      function MainCtrl() {
        var vm = this;
        vm.links = [
          {
            "path": "#home", "display": "Home"
          },
          {
            "path": "#portfolio", "display": "Portfolio"
          },
          {
            "path": "#contact", "display": "Contact"
          },
          {
            "path": "#about", "display": "About"
          },
          {
            "path": "#/", "display": "View source on GitHub"
          }
        ];
      }
    })();
    <!DOCTYPE html>
    <html ng-app="app">
    
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
    </head>
    
    <body ng-controller="MainCtrl as vm">
      <li ng-class="{ 'active': $first }" ng-repeat="link in vm.links"><a class="noPreventDefault" ng-click="vm.toggleNav()" ng-href="{{link.path}}">{{link.display}}</a></li>
    </body>
    
    </html>

    I hope it helps.