Imbrication complexe de partiels et de gabarits

ma question porte sur la façon de traiter l'imbrication complexe de templates (aussi appelé partials ) dans une application AngularJS.

la meilleure façon de décrire ma situation est avec une image que j'ai créée:

AngularJS Page Diagram

comme vous pouvez le voir cela a le potentiel d'être une application assez complexe avec beaucoup de modèles imbriqués.

L'application est une page, donc elle charge un index .html qui contient un élément div dans le DOM avec l'attribut ng-view .

pour le cercle 1 , vous voyez qu'il y a une navigation primaire qui charge les gabarits appropriés dans le ng-view . Je le fais en passant $routeParams au module principal de l'application. Voici un exemple de ce qui est dans mon application:

angular.module('myApp', []).
    config(['$routeProvider', function($routeProvider) {
        $routeProvider.                     
            when("/job/:jobId/zones/:zoneId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/zone_edit.html' }).
            when("/job/:jobId/initial_inspection", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/initial_inspection.html' }).
            when("/job/:jobId/zones/:zoneId/rooms/:roomId", { controller: JobDetailController, templateUrl: 'assets/job_list_app/templates/room_edit.html' })       

    }]);

dans le cercle 2 , le gabarit qui est chargé dans le ng-view a un Sous-navigation supplémentaire . Ce sous-nav a ensuite besoin de charger des modèles dans la zone ci - dessous-mais comme la vue ng est déjà utilisée, Je ne suis pas sûr de savoir comment faire cela.

je sais que je peux inclure des gabarits supplémentaires dans le 1er gabarit, mais ces gabarits vont tous être assez complexe. Je voudrais garder tous les modèles séparer afin de rendre l'application plus facile à mettre à jour et de ne pas avoir une dépendance sur le modèle parent doit être chargé afin d'accéder à ses enfants.

dans le cercle 3 , vous pouvez voir les choses devenir encore plus complexe. Il est possible que les modèles de sous-navigation aient un deuxième sous-navigation qui devra charger ses propres modèles ainsi dans la zone dans cercle 4

comment structurer une application AngularJS pour faire face à un tel enchevêtrement complexe de gabarits tout en les gardant tous séparés les uns des autres?

494
demandé sur Blackhole 2012-10-12 20:49:09

6 réponses

bien, puisque vous ne pouvez avoir actuellement qu'une seule directive ngView... J'utilise des commandes de directive imbriquées. Cela vous permet de configurer des échelles de templage et d'hériter (ou d'isoler) d'entre elles. En dehors de cela, j'utilise ng-switch ou même juste ng-show pour choisir les contrôles que j'affiche en fonction de ce qui vient de $routeParams.

EDIT voici un exemple de pseudo-code pour vous donner une idée de ce dont je parle. Avec une navigation de sous-marin imbriquée.

Voici l'application principale

<!-- primary nav -->
<a href="#/page/1">Page 1</a>
<a href="#/page/2">Page 2</a>
<a href="#/page/3">Page 3</a>

<!-- display the view -->
<div ng-view>
</div>

Directive pour la sous-navigation

app.directive('mySubNav', function(){
    return {
        restrict: 'E',
        scope: {
           current: '=current'
        },
        templateUrl: 'mySubNav.html',
        controller: function($scope) {
        }
    };
});

modèle pour la sous-navigation

<a href="#/page/1/sub/1">Sub Item 1</a>
<a href="#/page/1/sub/2">Sub Item 2</a>
<a href="#/page/1/sub/3">Sub Item 3</a>

modèle de page principale (de la navigation principale)

<my-sub-nav current="sub"></my-sub-nav>

<ng-switch on="sub">
  <div ng-switch-when="1">
      <my-sub-area1></my-sub-area>
  </div>
  <div ng-switch-when="2">
      <my-sub-area2></my-sub-area>
  </div>
  <div ng-switch-when="3">
      <my-sub-area3></my-sub-area>
  </div>
</ng-switch>

contrôleur pour une page principale. (de la navigation primaire)

app.controller('page1Ctrl', function($scope, $routeParams) {
     $scope.sub = $routeParams.sub;
});

Directive pour une sous-zone

app.directive('mySubArea1', function(){
    return {
        restrict: 'E',
        templateUrl: 'mySubArea1.html',
        controller: function($scope) {
            //controller for your sub area.
        }
    };
});
167
répondu Ben Lesh 2012-10-12 17:44:19

mise à jour: consultez le nouveau projet D'AngularUI pour résoudre ce problème


pour les sous-sections c'est aussi simple que de tirer des chaînes en ng-incluez:

<ul id="subNav">
  <li><a ng-click="subPage='section1/subpage1.htm'">Sub Page 1</a></li>
  <li><a ng-click="subPage='section1/subpage2.htm'">Sub Page 2</a></li>
  <li><a ng-click="subPage='section1/subpage3.htm'">Sub Page 3</a></li>
</ul>
<ng-include src="subPage"></ng-include>

ou vous pouvez créer un objet si vous avez des liens vers des sous-pages partout:

$scope.pages = { page1: 'section1/subpage1.htm', ... };
<ul id="subNav">
  <li><a ng-click="subPage='page1'">Sub Page 1</a></li>
  <li><a ng-click="subPage='page2'">Sub Page 2</a></li>
  <li><a ng-click="subPage='page3'">Sub Page 3</a></li>
</ul>
<ng-include src="pages[subPage]"></ng-include>

ou vous pouvez même utiliser $routeParams

$routeProvider.when('/home', ...);
$routeProvider.when('/home/:tab', ...);
$scope.params = $routeParams;
<ul id="subNav">
  <li><a href="#/home/tab1">Sub Page 1</a></li>
  <li><a href="#/home/tab2">Sub Page 2</a></li>
  <li><a href="#/home/tab3">Sub Page 3</a></li>
</ul>
<ng-include src=" '/home/' + tab + '.html' "></ng-include>

vous pouvez également mettre un contrôleur ng au niveau le plus élevé de chaque partielle

197
répondu ProLoser 2014-12-01 08:32:44

vous pouvez également consulter cette bibliothèque pour le même usage:

http://angular-route-segment.com

Il ressemble à ce que vous recherchez, et c'est beaucoup plus simple à utiliser que l'interface utilisateur du routeur. Du Démo site :

JS:

$routeSegmentProvider.

when('/section1',          's1.home').
when('/section1/:id',      's1.itemInfo.overview').
when('/section2',          's2').

segment('s1', {
    templateUrl: 'templates/section1.html',
    controller: MainCtrl}).
within().
    segment('home', {
        templateUrl: 'templates/section1/home.html'}).
    segment('itemInfo', {
        templateUrl: 'templates/section1/item.html',
        controller: Section1ItemCtrl,
        dependencies: ['id']}).
    within().
        segment('overview', {
            templateUrl: 'templates/section1/item/overview.html'}).

HTML de haut niveau:

<ul>
    <li ng-class="{active: $routeSegment.startsWith('s1')}">
        <a href="/section1">Section 1</a>
    </li>
    <li ng-class="{active: $routeSegment.startsWith('s2')}">
        <a href="/section2">Section 2</a>
    </li>
</ul>
<div id="contents" app-view-segment="0"></div>

imbriqué HTML:

<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>
26
répondu artch 2013-08-22 20:26:02

moi aussi je me débattais avec des vues emboîtées dans L'angle.

une fois que j'ai obtenu une prise de ui-routeur je savais que je ne retournerais jamais à la fonctionnalité de routage angulaire par défaut.

voici un exemple d'application qui utilise plusieurs niveaux de vues imbrication""

app.config(function ($stateProvider, $urlRouterProvider,$httpProvider) {
// navigate to view1 view by default
$urlRouterProvider.otherwise("/view1");

$stateProvider
    .state('view1', {
        url: '/view1',
        templateUrl: 'partials/view1.html',
        controller: 'view1.MainController'
    })
    .state('view1.nestedViews', {
        url: '/view1',
        views: {
            'childView1': { templateUrl: 'partials/view1.childView1.html' , controller: 'childView1Ctrl'},
            'childView2': { templateUrl: 'partials/view1.childView2.html', controller: 'childView2Ctrl' },
            'childView3': { templateUrl: 'partials/view1.childView3.html', controller: 'childView3Ctrl' }
        }
    })

    .state('view2', {
        url: '/view2',
    })

    .state('view3', {
        url: '/view3',
    })

    .state('view4', {
        url: '/view4',
    });
});

comme on peut le voir,il y a 4 vues principales (vue 1,vue 2,vue 3, vue 4) et la vue 1 A 3 vues d'enfant.

17
répondu Dan Ochiana 2014-09-03 11:51:44

vous pouvez utiliser ng-include pour éviter d'utiliser ng-views imbriquées.

http://docs.angularjs.org/api/ng/directive/ngInclude

http://plnkr.co/edit/ngdoc:example-example39@snapshot?p=preview

ma page d'index j'utilise ng-view. Puis sur mes sous-pages dont j'ai besoin d'avoir des cadres imbriqués. J'utilise ng-include. La démo montre une liste déroulante. J'ai remplacé le mien par un lien ng-click. Dans le fonction je mettrais $champ d'application.modèle = $champ d'application.modèles[0]; ou $scope.modèle = $champ d'application.templates[1];

$scope.clickToSomePage= function(){
  $scope.template = $scope.templates[0];
};
4
répondu Henry Mac 2014-03-27 17:28:33

Routeur angulaire ui-supporte les vues emboîtées. Je n'ai pas encore utilisé mais semble très prometteur.

http://angular-ui.github.io/ui-router /

2
répondu Adriaan Bouman 2014-04-23 15:41:30