26

I'm just starting out learning AngularJS. The router makes it dead simple to swap a single view (dom element) with a partial. In my case I might have 20 or so screens with a "full size" layout replacing the entire screen minus the common top header, like the following:

full size layout

This works fine. However, my application requires more than one layout! If I open some record, it might have a dynamic submenu with ~20 links where clicking on each link should only swap the right panel. Of course, I only want to fetch this dynamic submenu once.

detailed record with submenu

Perhaps opening up something else might have a completely different layout (with its own submenu - possibly horizontal).

Can Angular handle multiple layouts like this? Or would I actually need to build separate applications for each type of layout!? This type of thing is fairly trivial on other frameworks I've used such as GWT (with Activities and Places binding to URL), ExtJS, etc.

I found a similar (though perhaps not as complex) question posted here with no answer: Multiple layouts with Angular

1 Answer 1

35

What you're describing is nested views, which the default router does not support. There's a very popular third-party module for AngularJs called UI-Router that does support what you're asking (and a lot more, with really good documentation).

A demo of UI-Router doing what you're describing can be seen here:

http://plnkr.co/edit/3KgB5g?p=preview

Routes in UI-Router are called states and each state can have a parent state and children states, allowing you to nest layouts. In the example above, you can see this in action in app.js:

We define a state called personnel:

    .state('personnel', {
        url: "/personnel",
        templateUrl: "personnel.html"
    })

Then we define children states off of personnel (a list of the personnel that you can view):

    .state('personnel.list', {
      url: '/list',
      templateUrl: 'personnel.list.html',
      controller: 'PersonnelCtrl'
    })

And off of that, we can define even more children (when you click on a name, the detail of the person):

    .state('personnel.list.person', {
      url: '/:id',
      templateUrl: 'personnel.list.person.html',
      controller: function($scope, $stateParams){
        $scope.id = $stateParams.id
      }
    });

Notice that you can navigate to different people and only that part of the view changes while the parent states remain the same.

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect. Thank you. I'm surprised this isn't supported out of the box. It seems like a fairly standard requirement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.