Max
Max

Reputation: 1066

Angular UI Router - nested states and views

I have this index.html:

<body ng-controller="MainCtrl">
    <div class="app" ui-view>
          <h1>This should be visible while the app loads</h1>
    </div>
</body>

My config code:

angular.module('app').config(function ($locationProvider, $stateProvider) {
$locationProvider.html5Mode(true);
$stateProvider
    .state('login', {
        url: '/login',
        templateUrl: '/res/login/login.tpl.html'
    })
    .state('app', {
        url: '/',
        templateUrl: '/res/app/app.tpl.html',
        controller: 'AppCtrl',
        abstract: true,
        views:{
            header: {
                templateUrl: '/res/app/header.tpl.html'
            },
            toolbox: {
                templateUrl: '/res/app/toolbox.tpl.html'
            }
        }
    })
    .state('app.online', {
        url: 'online',
        templateUrl: '/res/app/online/online.tpl.html'
    })
    .state('app.history', {
        url: 'history',
        templateUrl: '/res/app/history/history.tpl.html'
    });
})    
.controller('MainCtrl', ['$state', function ($state) {

}])
.controller('LoginCtrl', [function () {

}])
.controller('AppCtrl', [function () {

}])
.controller('HeaderCtrl', [function () {

}])
.controller('SidebarCtrl', [function () {

}]);

app.tpl.html:

<div class="header" ui-view="header"></div>
<div class="content">
    <div class="toolbox" ui-view="toolbox"></div>
    <div class="content" ui-view>
         Place for the states - "app.online" and "app.history"
    </div>
</div>

I want the following to happen:

Currently, I can load /login successfully, but I don't understand why going to /online doesn't display app.tpl.html.

What am I missing?

Upvotes: 1

Views: 382

Answers (1)

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123861

The main change should be this state defintion:

.state('app', {
    url: '/',
    abstract: true,
    views:{
        '': {
            templateUrl: '/res/app/app.tpl.html',
            controller: 'AppCtrl',
        },
        'header@app': {
            templateUrl: '/res/app/header.tpl.html'
        },
        'toolbox@app': {
            templateUrl: '/res/app/toolbox.tpl.html'
        }
    }
})

this way we do pass the app.tpl.html into the unnamed ui-view="" in the index.html (root) next, we target with absolute naming that view, and inject the others:

'header@app': {
    templateUrl: '/res/app/header.tpl.html'
},
'toolbox@app': {
    templateUrl: '/res/app/toolbox.tpl.html'
}

Check the: View Names - Relative vs. Absolute Names cite:

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.

Upvotes: 1

Related Questions