jlengrand
jlengrand

Reputation: 12807

Multiple views to nested state

I am using ui-router and I try to create several views inside one of my nested states. In my logic, all of the views should be visible whenever the parent state is active.

I have read the wiki page on multiple named views multiple times, but could not get anything working yet. My state template would show up, but my views never do.

Here is a working plunker (You have to click on "Followers" in the navbar for the view to show up. Haven't figured why yet).

Important parts are the config

app.config([
    '$stateProvider', 
    '$urlRouterProvider',
    function ($stateProvider, $urlRouterProvider){
        $stateProvider
        .state('dashboard', {
            url: '/dashboard', 
            templateUrl: 'dashboard.html',
            controller: 'DashboardCtrl',
            authenticate: true
        }).state('dashboard.followers', {
            url: '/followers', 
            templateUrl: 'dashboard.followers.html',
            controller: 'DFollowersCtrl',                
            authenticate: true 
        }).state('dashboard.followers.add', {
            views: {
                'add': {
                    templateUrl: 'dashboard.followers.add.html',
                    controller: 'DFollowersAddCtrl',
                    authenticate: true
                }
            },
        });

        $urlRouterProvider.otherwise('dashboard');
    }
]);

The main dashboard template (level 2, using a generic ui-view)

<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
    <div class="flash-area">
        <flash-message duration="2000" show-close="true"></flash-message>
    </div>
    <ui-view></ui-view>
</div>

and the dashobard.followers specific level 3 view, that has a specific name

<div>

    <h1 class="page-header">Followers</h1>

    <div ui-view="add"></div>

</div>

The trick is coming from, I think, a combination of :

The final aim is to have more than one view in my template, but for now I reduced the attempts to only show the 'add' view.

I have seen several similar questions on SO already, such as this one or this other one but so far my attempts have not been fruitful.

Upvotes: 3

Views: 739

Answers (1)

Zhiliang Xing
Zhiliang Xing

Reputation: 1057

I think there are several mistakes here you made:

  1. if you want the url of dashboard.followers state and dashboard.followers.add state to be same, the child state dashboard.followers.add does not need the url option
  2. probably can be a mistake(I am not sure because no code is provided), if you don't use the views: { ... } named views, but just directly use url: '/followers', templateUrl: '/partials/dashboard.followers.html' angular just assume you want to insert the template in an unnamed <div ui-view></div> in the parents state's template not the root template. for example, in my example code, for state dashboard.followers, since it is a child state of dashboard, if I want to insert the template in root html template, I have to use views: { '@': { template: '<div><h1 class="page-header">Followers</h1><a ui-sref="dashboard.followers.add">add</a><div ui-view="add"></div></div>' } }

/* myApp module */
var myApp = angular.module('myApp', ['ui.router'])
  .config(['$stateProvider', function($stateProvider) {

    $stateProvider
      .state('landing', {
        url: '/',
        template: '<p>landing</p><a ui-sref="dashboard">dashboard</a>'
      })
      .state('dashboard', {
        url: '/dashboard',
        template: '<p>landing</p><a ui-sref="dashboard.followers">followers</a>'
      })
      .state('dashboard.followers', {
        url: '/followers',
        views: {
          '@': {
            template: '<div><h1 class="page-header">Followers</h1><a ui-sref="dashboard.followers.add">add</a><div ui-view="add"></div></div>'
          }
        }
      })
      .state('dashboard.followers.add', {
        views: {
          'add': {
            template: '<p>followers</p>'
          }
        }
      });
  }])
  .controller('MyAppCtrl', function($scope, $state /*, $stateParams*/ ) {
    $state.go("landing");
  });
<body ng-app="myApp" ng-controller="MyAppCtrl">

  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
  

  <div ui-view></div>

</body>

update

I made two plunkers to fit two different situation:

  1. if you want to dynamically load add state to ui-view="add" by a link, check this out.

  2. if you just want a sub template to be loaded always on dashboard.followers state, simply remove add states, and use views: {...} to load the add template in. here is the plunker.

Upvotes: 3

Related Questions