Cybrix
Cybrix

Reputation: 3318

Nested states not working with Angular UI Router

I am trying the lib for the first time and it looks like nested states aren't working as expected.

The states:

  1. The home state display content in 3 ui-views (top, left and content)
  2. The home.splash state must display the same ui-views and a new one (modal). Hopefully the inherited ui-views shouldn't update the DOM as they are already loaded...

Right now, I see the URL changing and here is my console: Console

Here is the jsfiddle link: http://jsfiddle.net/ffv0e2v7/3/

And here is the code:

'use strict';

angular.module('myApp', ['ui.router'])
    .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {

        $urlRouterProvider.otherwise('/home');

        $stateProvider
          .state('home', {
            url: '/home',
            views: {
              top     : { templateUrl: 'views/ui/top.html' },
              left    : { templateUrl: 'views/ui/left.html' },
              content : { templateUrl: 'views/ui/content.html' }
            }
          })
          .state('home.splash', {
            url    : '/splash',
            views: {
              /*top     : { templateUrl: 'views/ui/top.html' },
              left    : { templateUrl: 'views/ui/left.html' },
              content : { templateUrl: 'views/ui/content.html' },*/

              modal   : { templateUrl: 'views/modals/splash.html' }
            }
          });

    }]);

    <div ng-app="myApp">
        <!-- Views -->
        <div ui-view="top"></div>
        <div ui-view="left"></div>
        <div ui-view="content"></div>
        <div ui-view="modal"></div>

        <!-- Links -->
        <a ui-sref="home.splash">Splash</a>
        <a ui-sref="home">Home</a>

        <!-- Templates -->
        <script type="text/ng-template" id="views/ui/top.html">
          <div>top.html</div>
        </script>
        <script type="text/ng-template" id="views/ui/left.html">
          <div>left.html</div>
        </script>
        <script type="text/ng-template" id="views/ui/content.html">
          <div>content.html</div>
        </script>
        <script type="text/ng-template" id="views/modals/splash.html">
          <div>splash.html</div>
        </script>
    </div>

Thank you very much! I will award a bounty for the answer.

Upvotes: 0

Views: 501

Answers (1)

Chris T
Chris T

Reputation: 8216

You're almost there, but you need to target the named view in the root state using absolute name targetting.

Change this:

          modal   : { templateUrl: 'views/modals/splash.html' }

to this:

          'modal@'   : { templateUrl: 'views/modals/splash.html' }

What you're doing is saying target the named view 'modal' at the state "" (the empty string maps to the root state)

here's an updated fiddle: http://jsfiddle.net/0yanupup/1/


Read this page once or twice: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

View Names - Relative vs. Absolute Names

Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname@statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.

.state('report',{
    views: {
      'filters@': { },
      'tabledata@': { },
      'graph@': { }
    }
  })

Notice that the view names are now specified as absolute names, as opposed to the relative name. It is targeting the 'filters', 'tabledata', and 'graph' views located in the root unnamed template. Since it's unnamed, there is nothing following the '@'. The root unnamed template is your index.html.

Upvotes: 3

Related Questions