zhekaus
zhekaus

Reputation: 3194

How to hide content in the parent view when the user goes to a nested state and show it again when the user backs to the parent one?

I use ui-router and have two nested views. I’d like to hide some html-content in the parent view when the user goes to child state and show it again when the user backs to parent one. Could anybody give an advice how to achieve that?

It’s easy to do that using root scope and state change events but it looks like a dirty way, doesn’t it?

app.js

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

myApp.controller('ParentCtrl', function ($scope) {
    $scope.hideIt = false;
});

myApp.controller('ChildCtrl', function ( $scope) {
    $scope.$parent.hideIt = true;
});

myApp.config(function ($stateProvider, $urlRouterProvider) {
    $urlRouterProvider.otherwise('/');

    $stateProvider
        .state('parent', {
            url: '/parent',
            templateUrl: 'parent.html',
            controller: 'ParentCtrl'
        })
        .state('parent.child', {
            url: '/child',
            template: '<h2>Child view</h2>',
            controller: 'ChildCtrl'
        });
});

parent.html

<h2>Parent view</h2>
<div ng-hide="hideIt">
    <p>This text should be hidden when the user goes to the nested state.</p>
</div>
<a ui-sref="parent.child">Go to the nested view</a>
<div ui-view></div>

Upvotes: 1

Views: 3288

Answers (2)

Pindora
Pindora

Reputation: 63

One simple solution is to fill ui-view tag in the parent template with the content that you want gone when child state is loaded.

<ui-view>
  <h2>Parent view</h2>
  <div ng-hide="hideIt">
  <p>This text should be hidden when the user goes to the nested         state.</p>
<a ui-sref="parent.child">Go to the nested view</a>
</ui-view>

Upvotes: 4

wesww
wesww

Reputation: 2873

You should check out named views for this. That would probably be the best way to go. https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

Also, there's another thread that answered this question over here: https://stackoverflow.com/a/19050828/1078450

Here's the working code for nested named views, taken from that thread:

angular.module('myApp', ['ui.state'])
  .config(['$stateProvider', '$routeProvider',
    function($stateProvider, $routeProvider) {
      $stateProvider
        .state('test', {
          abstract: true,
          url: '/test',
          views: {
            'main': {
              template: '<h1>Hello!!!</h1>' +
                '<div ui-view="view1"></div>' +
                '<div ui-view="view2"></div>'
            }
          }
        })
        .state('test.subs', {
          url: '',
          views: {
            'view1@test': {
              template: "Im View1"
            },
            'view2@test': {
              template: "Im View2"
            }
          }
        });
    }
  ])
  .run(['$state', function($state) {
    $state.transitionTo('test.subs');
  }]);

http://jsfiddle.net/thardy/eD3MU/

Edit:

Adding some thoughts re the angular-breadcrumbs comment. I haven't used it myself, but at first glance it seems like subroutes shouldn't break the breadcrumbs. I'm just looking at the source code of their demo, around line 62. I'd have to spin it all up to really go about testing it, but it looks like they're doing almost the same thing with specifying views, and it works there: https://github.com/ncuillery/angular-breadcrumb/blob/master/sample/app.js#L62

  .state('room', {
    url: '/room',
    templateUrl: 'views/room_list.html',
    controller: 'RoomListCtrl',
    ncyBreadcrumb: {
      label: 'Rooms',
      parent: 'sample'
    }
  })
  .state('room.new', {
    url: '/new',
    views: {
      "@" : {
        templateUrl: 'views/room_form.html',
        controller: 'RoomDetailCtrl'
      }
    },
    ncyBreadcrumb: {
      label: 'New room'
    }
  })
  .state('room.detail', {
    url: '/{roomId}?from',
    views: {
      "@" : {
        templateUrl: 'views/room_detail.html',
        controller: 'RoomDetailCtrl'
      }
    },
    ncyBreadcrumb: {
      label: 'Room {{room.roomNumber}}',
      parent: function ($scope) {
        return $scope.from || 'room';
      }
    }
  })

Edit2:

This solution will not combine routes into one crumb

See the official demo

re: But I use angular-breadcrumb and in your solution they will be combined into one crum.

enter image description here

Upvotes: 2

Related Questions