web-dev-qa-db-fra.com

Angular routage ui-view dans une autre ui-view

Vue d'ensemble de la conception:

Nous avons deux onglets sur index html. Là nous routons ces onglets comme ça:

<div ui-view></div>

Sur un deuxième onglet nous avons un sélecteur, le contenu de cet onglet dans une autre vue ui comme celle-ci:

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

où vm.currentView est le nom de l'état de routage ('book1' et 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'
            }
        }
    });

Tout va bien, sauf une chose: le contenu des données et le nom d'une vue changent, mais pas le contenu d'un modèle.

Je l'ai résolu d'une autre manière (en excluant la conception 'ui-view à l'intérieur d'une autre ui-view' et des vues séparées dans les états). Mais je veux toujours savoir: "Comment faire cela en utilisant la conception 'ui-view inside ui-view'?"

Voici un exemple Plunker

13
SanSan-

Il est possible de faire 'ui-view à l'intérieur d'un autre ui-view'.

Disons que vous avez un index.html

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

et fournisseur d'état est comme ça: -

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

Dans books.html, vous avez des liens et une autre vue ui (vue imbriquée). Cliquez sur les liens pour renseigner la vue imbriquée imbriquée.

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>

maintenant fournisseur de l'Etat est: -

 $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 : - renseignez 'bookDetails' dans l'état 'books' ou vous pouvez dire que trouver 'bookDetails' dans l'état 'books' et le remplir avec l'objet 'views'.

17
Sanjay Singh Rawat

Comme je l'ai expliqué plus tôt, je veux juste faire 'ui-view à l'intérieur d'un autre ui-view', mais cela semble impossible. J'ai trouvé deux façons de résoudre ce "bug" (?).

Première manière: Excluez 'ui-view à l'intérieur d'une autre ui-view' et utilisez 'ng-include'

Variante la plus simple avec un changement de code minimal. Comme vous voyez ici , j'ai remplacé 

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

avec 

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

et ajouter une fonction au contrôleur, 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';
            }
        }

Deuxième manière: enregistrer formellement la 'vue ui dans une autre vue ui' et séparer les vues par les états

Et comme vous le voyez ici , j’économise formellement 'ui-view à l’intérieur de ui-view', mais en fait, je remplace tout à fait un seul ui-view par un modèle à partir d’un autre unique ui-view voir par nom).

$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'
        });

Où contenu de tab2.html est:

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

Quand le sélecteur change, j'appelle vm.changeHandbook (vm.selectedBook)} pour changer de modèle:

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

C'est un moyen très étrange et difficile, mais au final, nous obtenons un code plus propre.

0
SanSan-