Kousha
Kousha

Reputation: 36219

ui-router with multiple views on an abstract parent

I am trying to create a route hierarchy with ui-router, and I am having issues.

I have three layers of templates: guest template, user template, admin template. So my index.html page is:

<html>
<head><!-- All common JS/CSS files such as Foundation and AngularJS --></head>
<body>
    <!-- Some common directive such as <reveal></reveal> used for dialog/popin pages -->
    <ui-view></ui-view>
</body>
</html>

Then, for each of my layers, I have another template. For instance, for guest I have:

guest.html

<nav><!-- The navigation for guest page --></nav>
<ui-view></ui-view>

and for user it is slightly more complicated:

user.html

<nav><!-- The navigation for user page --></nav>
<ui-view="left"></ui-view>
<ui-view="main"></ui-view>
<ui-view="right"></ui-view>

Now, my state for guest is quite simple:

$stateProvider
    .state('guest', {
        abstract: true,
        templateUrl: 'path/to/guest.html' 
    })
    .state('guest.login', {
        url: '/login/',
        template: '<login></login>'
    });

Problem rises with user. Just like above, I create an abstract state that adds the user.html to the template and gives me access to the 3 views. Normally, if I then extend the state, I can write to the three states as

.state('user.home', {
    url: '/home/',
    views: {
        'left':  { template: 'Left template' },
        'main':  { template: 'Main template' },
        'right': { template: 'Right template'}
    }
});

The problem is that I want to define another abstract here, called user.schedule, and these abstract state has a few children. When I do define this state, I still want to have access to the three views I had originally created in the user.html. However, since this is an abstract class, I need to define the templates for it.

I cannot figure out how to proceed with this abstract class. What I "thought" I should do was:

.state('user.schedule', {
    abstract: true,
    views: {
        'left':  { template: '<ui-view></ui-view>' },
        'main':  { template: '<ui-view></ui-view>' },
        'right': { template: '<ui-view></ui-view>'}
    }
})
.state('user.schedule.view', {
    url: '/schedule/:day/:month/:year',
    views: {
        'left':  { template: 'This should work?' },
        'main':  { template: 'But it does not' },
        'right': { template: 'I even tried giving the ui above a name and calling them here'}
    }
})

What can I do?

Upvotes: 3

Views: 3721

Answers (1)

Jonathan Wilson
Jonathan Wilson

Reputation: 4305

I'm pretty sure the left/main/right viewports you defined in user.html are only available to immediate children of the user abstract state. It would then follow that the views you declare in your user.schedule.view state must correspond to named viewports in the user.schedule template.

Try naming the viewports in your user.schedule templates left,main,and right. It's possible that there may be a name collision but hey, it's worth a shot.

ie. Change this:

.state('user.schedule', {
    abstract: true,
    views: {
        'left':  { template: '<ui-view></ui-view>' },
        'main':  { template: '<ui-view></ui-view>' },
        'right': { template: '<ui-view></ui-view>'}
    }
})
.state('user.schedule.view', {
    url: '/schedule/:day/:month/:year',
    views: {
        'left':  { template: 'This should work?' },
        'main':  { template: 'But it does not' },
        'right': { template: 'I even tried giving the ui above a name and calling them here'}
    }
})

to this:

.state('user.schedule', {
    abstract: true,
    views: {
        'left':  { template: '<ui-view="left"></ui-view>' },
        'main':  { template: '<ui-view="main"></ui-view>' },
        'right': { template: '<ui-view="right"></ui-view>'}
    }
})
.state('user.schedule.view', {
    url: '/schedule/:day/:month/:year',
    views: {
        'left':  { template: 'This should work?' },
        'main':  { template: 'But it does not' },
        'right': { template: 'I even tried giving the ui above a name and calling them here'}
    }
})

Also, I'm not sure that this is proper form:

<ui-view="name"></ui-view>

I am sure that this is proper form (per the docs):

<ui-view ui-view="name"></ui-view>

or

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

Upvotes: 2

Related Questions