19

I am looking to show a block of HTML only when $state.current.name equals about.list. So far I have the following code but it doesn't seem to be toggling the element depending on the state.

index.html

<nav class="global-navigation">
    <ul class="list">
    <li class="list-item">
      <a class="list-item-link" ui-sref="home">
        Home
      </a>
    </li>
    <li class="list-item">
      <a class="list-item-link" ui-sref="about">
        About
      </a>
    </li>
     <li class="list-item" ng-show="$state.current.name == 'about.list'">
      <a class="list-item-link" ui-sref="about.list">
        List
      </a>
    </li>
    </ul>
  </nav>

app.js

var myApp = angular.module('myApp', ['ui.router'])

  .config(['$urlRouterProvider', '$stateProvider', 

    function($urlRouterProvider, $stateProvider) {

    $urlRouterProvider.otherwise('/404.html');

    $stateProvider.

      // Home
      state('home', {
        url: '/',
        templateUrl: 'partials/_home.html',
        controller: 'homeCtrl'
      }).

      // About
      state('about', {
        url: '/about',
        templateUrl: 'partials/_about.html',
        controller: 'aboutCtrl'
      }).

      // About List
      state('about.list', {
        url: '/list',
        controller: 'aboutCtrl',
        templateUrl: 'partials/_about.list.html',
        views: {
          'list': { templateUrl: 'partials/_about.list.html' }
        }
      });

  }]

);
Matt
  • 2,317
  • 7
  • 41
  • 52

3 Answers3

35

You can use filters like isState or includedByState.

ng-if="'about.list' | isState" // exactly 'about.list'

ng-if="'about' | includedByState" // works for about and its children about.*
devside
  • 2,171
  • 1
  • 19
  • 23
27

Or

JS

.run(function ($state,$rootScope) {
    $rootScope.$state = $state;
})

HTML

data-ng-show="$state.includes('about.list')"
Whisher
  • 31,320
  • 32
  • 120
  • 201
  • This worked out for me :) Would you say this is the best way to conditionally show/hide something depending on state? – Matt Mar 30 '14 at 20:00
  • It's a way it's up to you ..... :) I can only sqy that its the ui-router way take a look at https://github.com/angular-ui/ui-router/blob/master/sample/index.html#L51 – Whisher Mar 30 '14 at 20:55
  • +1 @Brian This is the better solution in your case, because you have an application wide menu. While I think I got the problem right, I failed to mention that every "top level" view/controller pair would then need `$state` injected into it. This solution puts the `$state` variable on the `$rootScope` making the variable accessible to any child scopes. – Sunil D. Mar 31 '14 at 02:26
11

The view (html) doesn't know about the variable $state. It only knows the $scope that is associated with the view.

You can expose the $state variable on the $scope inside the controller that is associated with this view (you might have to inject $state into your controller as well):

$scope.uiRouterState = $state;

Then change the expression in your markup slightly:

<li class="list-item" ng-show="uiRouterState.current.name == 'about.list'">
Sunil D.
  • 17,983
  • 6
  • 53
  • 65
  • Hm, I couldn't get this approach to work and I injected $state into the controller. – Matt Mar 30 '14 at 19:59