Złożone zagnieżdżanie częściowych i szablonów

Moje pytanie dotyczy sposobu radzenia sobie ze złożonym zagnieżdżaniem szablonów (zwanych również partiami) w aplikacji AngularJS.

Najlepszym sposobem na opisanie mojej sytuacji jest obraz, który stworzyłem:

Diagram Strony AngularJS

Jak widać, może to być dość złożona aplikacja z wieloma zagnieżdżonymi modelami.

Aplikacja jest jednostronicowa, więc ładuje indeks .html , który zawiera element div w DOM z ng-view atrybut.

Dla okręgu 1 widać, że istnieje podstawowa nawigacja, która ładuje odpowiednie szablony do ng-view. Robię to przekazując $routeParams do głównego modułu aplikacji. Oto przykład tego, co znajduje się w mojej aplikacji:

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

    }]);

W okręgu 2, szablon, który jest ładowany do ng-view ma dodatkową sub-nawigację . Ta podpunkt nav musi następnie załadować szablony do obszaru pod nim - ale ponieważ ng-view jest już używany, nie jestem pewien jak to zrobić.

Wiem, że mogę dołączyć dodatkowe szablony w 1. szablonie, ale wszystkie te szablony będą dość skomplikowane. Chciałbym, aby wszystkie szablony były oddzielone, aby ułatwić aktualizację aplikacji i nie uzależniać się od szablonu nadrzędnego, który musi być załadowany, aby uzyskać dostęp do jego dzieci.

W kręgu 3 widać, że sprawy stają się jeszcze bardziej złożone. Istnieje potencjał, że sub-nawigacja szablony będą miały 2. pod-nawigację , która będzie musiała załadować własne szablony również do obszaru w okręgu 4

Jak zorganizować aplikację AngularJS, aby poradzić sobie z tak złożonym zagnieżdżaniem szablonów, trzymając je wszystkie oddzielnie od siebie?

Author: Blackhole, 2012-10-12

6 answers

Cóż, ponieważ obecnie możesz mieć tylko jedną dyrektywę ngView... Używam zagnieżdżonych kontrolek. Pozwala to na konfigurację szablonów i dziedziczenie (lub izolowanie) zakresów między nimi. Poza tym używam ng-switch lub nawet po prostu ng-show, aby wybrać, które kontrolki wyświetlam na podstawie tego, co nadchodzi z $routeParams.

EDIT Oto przykładowy pseudo-kod, aby dać ci wyobrażenie o tym, o czym mówię. Z zagnieżdżoną nawigacją podwodną.

Oto główna aplikacja Strona

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

Dyrektywa do nawigacji sub

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

Szablon do nawigacji sub

<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>

Szablon dla strony głównej (z primary nav)

<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>

Kontroler dla strony głównej. (z głównego nav)

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

Dyrektywa dla podobszaru

app.directive('mySubArea1', function(){
    return {
        restrict: 'E',
        templateUrl: 'mySubArea1.html',
        controller: function($scope) {
            //controller for your sub area.
        }
    };
});
 167
Author: Ben Lesh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-12 17:44:19

UPDATE: Sprawdź nowy projekt AngularUI, aby rozwiązać ten problem]}


Dla podrozdziałów jest to tak proste, jak wykorzystanie ciągów w 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>

Lub możesz utworzyć obiekt w przypadku, gdy masz linki do podstron w całym miejscu:

$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>

Lub możesz nawet użyć $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>
Można również umieścić kontroler ng na najwyższym poziomie każdego z części
 197
Author: ProLoser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-01 08:32:44

Możesz sprawdzić tę bibliotekę również w tym samym celu:

Http://angular-route-segment.com

Wygląda jak to, czego szukasz, i jest znacznie prostszy w użyciu niż ui-router. Ze strony demo :

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 najwyższego poziomu:

<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>

Zagnieżdżony HTML:

<h4>Section 1</h4>
Section 1 contents.
<div app-view-segment="1"></div>
 26
Author: artch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-22 20:26:02

Ja też zmagałem się z zagnieżdżonymi widokami w Angular.

Kiedy zdobyłem UI-router wiedziałem, że nigdy nie wrócę do domyślnej funkcji routingu angular.

Oto przykładowa aplikacja, która używa wielu poziomów zagnieżdżania widoków

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

Jak widać są 4 główne widoki (view1,view2,view3, view4) i view1 ma 3 widoki potomne.

 17
Author: Dan Ochiana,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-03 11:51:44

Możesz użyć ng-include, aby uniknąć zagnieżdżania ng-views.

Http://docs.angularjs.org/api/ng/directive/ngInclude
http://plnkr.co/edit/ngdoc:example-example39@snapshot?p=preview

Moja strona indeksu używam ng-view. Następnie na moich podstronach, które muszę mieć zagnieżdżone ramki. Używam ng-include. Demo pokazuje listę rozwijaną. Mój zamieniłem na link ng-click. W funkcji umieściłbym $scope.template = $ scope.templates[0]; lub $scope.szablon = $ scope.szablony [1];

$scope.clickToSomePage= function(){
  $scope.template = $scope.templates[0];
};
 4
Author: Henry Mac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-27 17:28:33

Angular ui-router obsługuje zagnieżdżone widoki. Nie używałem go jeszcze, ale wygląda bardzo obiecująco.

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

 2
Author: Adriaan Bouman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 15:41:30