3

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 :

  • I want to use level 3 nesting
  • Level 2 uses a generic ui-view, because it may contains my dashboard or something else.
  • Level 3 contains specific views, as it is where I want to use "views" and not "states" (as far as I understood, at least).

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.

  • I can access my "add" view directly if I reach its URL (when I try setting one)
  • But the dashboard.followers state does not get populated by the views.
Community
  • 1
  • 1
jlengrand
  • 12,152
  • 14
  • 57
  • 87
  • /dashboard/followers/followers -> dashboard.followers.add? – coma Apr 12 '16 at 06:27
  • If you mean that I can access the view directly via the url, yes you are right. However the idea is to make it load in my followers view directly ( /dashboard/followers). – jlengrand Apr 12 '16 at 06:31
  • 1
    No, what I was trying to show you is that /dashboard/followers/followers it's an ugly path, what about /dashboard/followers/add?. Anyway, try crafting a codepen, cheers. – coma Apr 12 '16 at 08:22
  • Hey, you are right. It actually is what I have in my last commit. It must be a remnant of a bad test. Sorry for that. Will open a codepen during lunch :). – jlengrand Apr 12 '16 at 09:48
  • @jlengrand give me some feedback on my answer, if it's not working let me know – Zhiliang Xing Apr 12 '16 at 12:32
  • Thanks guys. I created 2 plunkers with some simplifications for you to see. I don't think the solution from Zhiliang solved my issue yet. Or at least I did not get it to work. https://plnkr.co/edit/mw2QcGcduN6ki9acLJww – jlengrand Apr 12 '16 at 21:36
  • so actually you want your follower state to show up without click? – Zhiliang Xing Apr 12 '16 at 21:55
  • No, What I want is the dashboard.followers.add to be inserted into the followers state. In the current plunker, when the dashboardfollowers state is selected, the ui-view that is named "add" stays empty even though the configuration requests for dashboard.followers.add to be used. – jlengrand Apr 13 '16 at 07:11

1 Answers1

3

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.

Zhiliang Xing
  • 1,057
  • 1
  • 8
  • 19
  • @jlengrand this seems to work, give us some feedback and I'll add my own answer if this one is not what you are looking for. – coma Apr 12 '16 at 10:08
  • Thanks. I try your snippet but unfortunately if I do that it hides my left bar. You can see the result in this plunker : https://plnkr.co/edit/mw2QcGcduN6ki9acLJww (click on followers) – jlengrand Apr 12 '16 at 21:35
  • I suggest you to read this [document](https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views), it is really helpful for you to understand how the nested named view works. I have updated my answer for you :) – Zhiliang Xing Apr 12 '16 at 21:42
  • Thanks Zhiliang. The page you are linking too is the one I link in the description of the issue already :). That is how I got to the current configuration. In your plunker. when the dashboard.followers state is selected, the dashboard.followers.add does not get loaded in the ui-view="add". That is my current issue. – jlengrand Apr 13 '16 at 07:13
  • sorry actually changed it based on the old one, on my pc it's the new version, i m not familiar with plunker, just one thing to check, you wanna load add states to the ui-view="add" by default without click?(basically u just wanna loaded the template in), or u wanna a link to click then switch to state `add` then load the template. – Zhiliang Xing Apr 13 '16 at 19:06
  • i have added the new answers @jlengrand – Zhiliang Xing Apr 13 '16 at 19:28
  • The second version is exactly what I wanted, thanks a lot! I had not tried to put all my views in the same state, but it sounds logical now that you showed it :). – jlengrand Apr 14 '16 at 08:02