Question Imbrication complexe de partiels et de gabarits


Ma question concerne la manière d’aborder la nidification complexe de modèles (aussi appelé partiels) 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 constater, cela peut être une application assez complexe avec de nombreux modèles imbriqués.

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

Pour le cercle 1, Vous voyez qu'il existe une navigation principale qui charge les modèles appropriés dans le ng-view. Je le fais en passant $routeParams vers le module principal de l'application. Voici un exemple de ce que contient 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' })       

    }]);

En cercle 2, le modèle chargé dans le ng-view a un autre sous-navigation. Ce sous-nav doit alors charger des gabarits dans la zone située en dessous, mais comme ng-view est déjà utilisé, je ne suis pas sûr de savoir comment procéder.

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

En cercle 3, vous pouvez voir que les choses deviennent encore plus complexes. Il est possible que les modèles de sous-navigation aient un 2ème sous-navigation qui devra charger ses propres modèles aussi bien dans la zone cercle 4

Comment peut-on structurer une application AngularJS pour faire face à une telle imbrication complexe de modèles tout en les gardant séparés les uns des autres?


493
2017-10-12 16:49


origine


Réponses:


Eh bien, puisque vous ne pouvez actuellement avoir qu'une seule directive ngView ... j'utilise des contrôles de directive imbriqués. Cela vous permet de définir des modèles et d'hériter (ou d'isoler) des étendues entre eux. En dehors de cela, j'utilise ng-switch ou même simplement ng-show pour choisir les commandes que j'affiche en fonction de ce qui vient de $ routeParams.

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

Voici la page principale de l'application

<!-- 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 navigation secondaire

<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 pour une page principale (à partir 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. (à partir du nav principal)

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.
        }
    };
});

166
2017-10-12 17:21



METTRE À JOUR:  Découvrez le nouveau projet d'AngularUI pour résoudre ce problème


Pour les sous-sections, il est aussi simple que de tirer parti des chaînes de caractères de ng-include:

<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 dans le cas où 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 placer un ng-controller au plus haut niveau de chaque partie


196
2017-10-15 21:03



Vous pouvez également consulter cette bibliothèque dans le même but:

http://angular-route-segment.com

Il ressemble à ce que vous recherchez et il est beaucoup plus simple à utiliser que l'interface utilisateur. Du site de démonstration:

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>

HTML imbriqué:

<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>

26
2017-08-15 10:05



Moi aussi, je me débattais avec des vues imbriquées dans Angular.

Une fois que j'ai eu une emprise de ui-routeur Je savais que je ne revenais jamais à la fonctionnalité de routage angulaire par défaut.

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

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 (view1, view2, view3, view4) et view1 a 3 vues enfant.


17
2017-09-03 11:51



Vous pouvez utiliser ng-include pour éviter d'utiliser ng-views imbriqués.

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 images imbriquées. J'utilise ng-include. La démo montre une liste déroulante. J'ai remplacé le mien par un lien ng-click. Dans la fonction je mettrais $ scope.template = $ scope.templates [0]; ou $ scope.template = $ scope.templates [1];

$scope.clickToSomePage= function(){
  $scope.template = $scope.templates[0];
};

4
2018-03-27 17:19



Angi-routeur angulaire prend en charge les vues imbriquées. Je ne l'ai pas encore utilisé mais semble très prometteur.

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


2
2018-04-23 15:41