web-dev-qa-db-fra.com

Angular UI-Router: enfant utilisant la vue des parents

sous forme d'histoire:

Ce que je recherche ici, c'est une configuration maître-détail. Le masque est sous forme de liste et lorsque je clique sur un lien (par rapport à une ligne/un enregistrement particulier (ou un compte dans ce cas)), je veux voir les détails dans la vue principale (littéralement, la vue "principale": <div class="container" ui-view="main"></div>).

Je souhaite le faire et conserver ma structure d'URL (/accounts pour la liste des comptes; /accounts/:id pour la version détaillée) mais je veux que la vue de détail utilise la vue que la liste utilisait.

Ce que j'ai actuellement

index.html

...
<div class="container" ui-view="main"></div>
...

accounts.js

$stateProvider
    .state ('accounts', {
        url: '/accounts',
        views: {
            'main': {
                controller: 'AccountsCtrl',
                templateUrl: 'accounts/accounts.tpl.html'
            }
        },
        data: { pageTitle: 'Account' }
    })
    .state ('accounts.detail', {
        url: '/:id',
        views: {
            'main': {
                controller: 'AccountDetailCtrl',
                templateUrl: 'accounts/detail.tpl.html'
            }
        },
        data: { pageTitle: 'Account Detail' }
    });

À ce stade, le /accounts la route fonctionne comme prévu. Il affiche accounts/accounts.tpl.html correctement dans la vue main. Dans ce html chaque ligne du répéteur le relie à son /accounts/:id URL, que je gère avec l'état imbriqué accounts.detail.

Ce qui est probablement évident pour la majorité d'entre vous qui en savent plus que moi à ce sujet, mon accounts.detail s'affichera dans la vue mainsi cette vue nommée existe dans le modèle accounts/accounts.tpl.html. C'est bien vrai.

Mais ce n'est pas ce que je veux. Je veux le accounts.detail trucs à rendre dans la vue parent main; Je veux le html de accounts/detail.tpl.html à remplacer le html de accounts/accounts.tpl.html trouvé dans index.html: <div class="container" ui-view="main"></div>.

Alors, comment pourrais-je accomplir cela?

MA SOLUTION DANS LE CONTEXTE L'astuce consiste, comme le dit la réponse, à configurer le schéma d'URL pour identifier quel état enfant est "par défaut". La façon dont j'interprète ce code en anglais simple est que la classe parent est abstraite avec l'URL appropriée et que la classe enfant "par défaut" a la "même" URL (indiquée par '').

Si vous avez besoin de plus de clarté, postez simplement un commentaire et je partagerai plus de conseils.

.config(function config( $stateProvider ) { $stateProvider
    .state ('accounts', {
        abstract: true,
        url: '/accounts',
        views: {
            'main': {
                templateUrl: 'accounts/accounts.tpl.html',
                controller: 'AccountsCtrl'
            }
        },
        data: { pageTitle: 'Accounts' }
    })
    .state ('accounts.list', {
        url: '',
        views: {
            'main': {
                templateUrl: 'accounts/list.tpl.html',
                controller: 'AccountsListCtrl'
            }
        },
        data: { pageTitle: 'Accounts List' }
    })
    .state ('accounts.detail', {
        url: '/:id',
        views: {
            'main': {
                templateUrl: 'accounts/detail.tpl.html',
                controller: 'AccountDetailCtrl'
            }
        },
        data: { pageTitle: 'Account Detail' }
    });
32
Honus Wagner

On dirait que vous ne voulez tout simplement pas que les vues soient hiérarchiques. Pour ce faire, changez simplement le nom du deuxième état en detail.

Notez cependant que, ce faisant, vous perdrez toutes les propriétés hiérarchiques de l'arborescence d'état (l'état des comptes du code du contrôleur par exemple).

Si vous voulez garder les contrôleurs hiérarchiques, mais effectuez un remplacement du HTML, je créerais un autre parent au-dessus des deux autres qui prend en charge la logique du contrôleur, mais n'a qu'une vue extrêmement simple <div ui-view=""></div>.

Par exemple:

$stateProvider
    .state('app', { url: '', abstract: true, template: 'parent.html', controller: 'ParentCtrl' })
    .state('app.accounts', { url: '/accounts', templateUrl: 'accounts.tpl.html', controller: 'AccountsCtrl' })
    .state('app.detail', { url: '/accounts/:id', templateUrl: 'detail.tpl.html', controller: 'AccountDetailCtrl' });
38
Matt Way

Vous pouvez utiliser '@' pour définir un chemin absolu vers l'interface utilisateur de votre choix. Par exemple: "detail @ contacts": {}, où cela cible absolument la vue "détail" dans l'état "contacts". dans contacts.html

Source: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views

14
Jakub