17

Conception overview:

We have two tabs on index html. There we routing those tabs like that:

<div ui-view></div>

On a second tab we have a selector, that switch tab's content in another ui-view like that:

<div ui-view="{{vm.currentView}}"></div>

where vm.currentView is a name of routing state ('book1' and etc.).

 .state('tab2', {
        abstract: true,
        templateUrl: 'tab2.html',
        controller: 'Tab2Controller',
        controllerAs: 'vm'
    })
    .state('tab2.content', {
        url: '/tab2',
        views: {
            '': {
                templateUrl: 'tab2.html'
            },
            'book1@tab2': {
                templateUrl: 'tab2-book1.html'
            },
            'book2@tab2': {
                templateUrl: 'tab2-book2.html'
            },
            'book3@tab2': {
                templateUrl: 'tab2-book3.html'
            },
            'book4@tab2': {
                templateUrl: 'tab2-book4.html'
            }
        }
    });

Everything is fine, except one thing: data content and name of a view is changing, but a template content isn't.

I resolved it by another way (based on exclude 'ui-view inside another ui-view' conception and separate views in states). But i still want to know: "How to do this with using 'ui-view inside ui-view' conception?"

Here's a Plunker Example

5
  • Maybe this question could be useful. Commented Nov 13, 2015 at 15:58
  • Same results. ui-veiw can provide a template only once. Commented Nov 16, 2015 at 9:33
  • It doesn't, it just reads the name only when the state changes. Commented Nov 16, 2015 at 9:48
  • exactly. last thing that will must to resolve it's how to transmit index of template. Commented Nov 16, 2015 at 11:41
  • That's means exclude 'ui-view in ui-view' conception. Yeah, I used ng-include in one of answer (i made directive that's provide templates, looks like this). I just want to know is it possible to make 'ui-view inside ui-view' conception or not? And it seems as not. Commented Nov 16, 2015 at 12:36

2 Answers 2

21

Its possible to make 'ui-view inside another ui-view'.

Lets say you have an index.html

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

and state provider is like this :-

$stateProvider
   .state('books', {
        parent: 'pages',
        url: '/books',                   
        views: {
            'content@': {
                 templateUrl: 'books.html',
                 controller: 'BooksController'
             }
        }
   })

In books.html you have some links and another ui-view (nested ui-view). On click of links populate the nested ui-view.

books.html

<div>
     <a ui-sref="book1"></a>
     <a ui-sref="book2"></a>
     <a ui-sref="book3"></a>
</div>
<!-- nested ui-view -->
<div ui-view="bookDetails"></div>

now state provider is :-

 $stateProvider
    .state('books', {
        parent: 'pages',
        url: '/books',                   
        views: {
            'content@': {
                 templateUrl: 'books.html',
                 controller: 'BooksController'
             }
        }
    })
    .state('book1', {
        parent: 'books',                  
        views: {
            'bookDetails@books': {
                 templateUrl: 'book1.html',
                 controller: 'BookOneController'
             }
        }
    })
    .state('book2', {
        parent: 'books',                 
        views: {
            'bookDetails@books': {
                 templateUrl: 'book2.html',
                 controller: 'BookTwoController'
             }
        }
    })
    .state('book3', {
        parent: 'books',                
        views: {
            'bookDetails@books': {
                 templateUrl: 'book3.html',
                 controller: 'BookThreeController'
             }
        }
    })

bookDetails@books :- populate 'bookDetails' ui-view in 'books' state or we can say that find 'bookDetails' ui-view inside 'books' state and populate it with 'views' object.

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

1 Comment

So, that's a cool answer. Named ui-view at root. How i can't see that earlier.. excelent.. I make a plnkr. Here is PS: sry for waiting..
0

As i explained earlier i just want to make 'ui-view inside another ui-view', but it seems impossible. I found two ways to resolve this "bug"(?).

First way: Exclude 'ui-view inside another ui-view' and use 'ng-include'

Simplest variant with minimal change of code. As you see here, i replaced

 <div ui-view="{{vm.currentView}}"></div>

with

 <ng-include src="vm.getTemplateUrl(vm.selectedBook.id)"/>

and add function to controller, thats switch templates:

function getTemplateUrl(id) {
            switch (id) {
                case 0:
                    return 'tab2-book1.html';
                case 1:
                    return 'tab2-book2.html';
                case 2:
                    return 'tab2-book3.html';
                case 3:
                    return 'tab2-book4.html';
                default:
                    return 'tab2-book4.html';
            }
        }

Second way: Formally save 'ui-view inside another ui-view' and separate views by states

And as you see here, formally i save 'ui-view inside ui-view', but in fact i just fully replace single ui-view by template from another single ui-view (can't set second ui-view by name).

$urlRouterProvider
        .when('/tab2', '/tab2/book4');

    $stateProvider
        .state('tab2', {
            url: '/tab2',
            templateUrl: 'tab2.html'
        })
        .state('tab2.book1', {
            url: '/book1',
            params: {
                id: 0
            },
            templateUrl: 'tab2-book1.html',
            controller: 'Tab2Controller',
            controllerAs: 'vm'
        })
        .state('tab2.book2', {
            url: '/book2',
            params: {
                id: 1
            },
            templateUrl: 'tab2-book2.html',
            controller: 'Tab2Controller',
            controllerAs: 'vm'
        })
        .state('tab2.book3', {
            url: '/book3',
            params: {
                id: 2
            },
            templateUrl: 'tab2-book3.html',
            controller: 'Tab2Controller',
            controllerAs: 'vm'
        })
        .state('tab2.book4', {
            url: '/book4',
            params: {
                id: 3
            },
            templateUrl: 'tab2-book4.html',
            controller: 'Tab2Controller',
            controllerAs: 'vm'
        });

Where content of tab2.html is:

<ui-view class="page-container"></ui-view>

When selector changed i call vm.changeHandbook(vm.selectedBook) to switch templates:

function changeHandbook(ref) {
            $state.go(ref.value);
        }

This is most weird and difficult way, but in the end we get more cleaner code.

Comments

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.