Aninhamento complexo de parciais e modelos

Minha pergunta envolve como lidar com o aninhamento complexo de modelos (também chamados parciais ) em um aplicativo AngularJS.

A melhor maneira de descrever minha situação é com uma imagem que criei:

Diagrama de Páginas AngularJS

Como você pode ver, isso tem o potencial de ser um aplicativo bastante complexo com muitos modelos nesteds.

O aplicativo é de página única, portanto, ele carrega um index.html que contém um elemento div no DOM com o atributo ng-view .

Para o círculo 1 , você vê que existe uma navegação primária que carrega os modelos apropriados na ng-view . Eu estou fazendo isso passando $routeParams para o módulo principal do aplicativo. Aqui está um exemplo do que está no meu aplicativo:

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

No círculo 2 , o modelo que é carregado na ng-view possui uma sub-navegação adicional. Este sub-nav precisa então carregar templates na área abaixo dele – mas como o ng-view já está sendo usado, não sei como fazer isso.

Eu sei que posso include modelos adicionais no primeiro modelo, mas esses modelos serão bem complexos. Eu gostaria de manter todos os modelos separados para facilitar a atualização do aplicativo e não ter uma dependência do modelo pai ter que ser carregado para acessar seus filhos.

No círculo 3 , você pode ver as coisas ainda mais complexas. Existe o potencial que os modelos de sub-navegação terão uma segunda sub-navegação que precisará carregar seus próprios modelos, bem como a área no círculo 4

Como é possível estruturar um aplicativo AngularJS para lidar com esse aninhamento complexo de modelos, mantendo-os todos separados um do outro?

Bem, desde que você atualmente só pode ter uma diretiva ngView … Eu uso controles diretivos nesteds. Isso permite que você defina modelos e herde (ou isole) escopos entre eles. Fora disso eu uso ng-switch ou mesmo apenas ng-show para escolher quais controles eu estou exibindo com base no que está vindo de $ routeParams.

EDIT Aqui está um exemplo de pseudo-código para lhe dar uma ideia do que estou falando. Com uma sub navegação aninhada.

Aqui está a página principal do aplicativo

  Page 1 Page 2 Page 3  

Directiva para a sub navegação

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

modelo para a sub navegação

 Sub Item 1 Sub Item 2 Sub Item 3 

template para uma página principal (do nav primário)

   

Controlador para uma página principal. (do nav primário)

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

Directiva para uma subárea

 app.directive('mySubArea1', function(){ return { restrict: 'E', templateUrl: 'mySubArea1.html', controller: function($scope) { //controller for your sub area. } }; }); 

ATUALIZAÇÃO: Confira o novo projeto do AngularUI para resolver este problema


Para subseções, é tão fácil quanto alavancar strings em ng-include:

   

Ou você pode criar um object no caso de ter links para subpáginas em todo o lugar:

 $scope.pages = { page1: 'section1/subpage1.htm', ... }; 
   

Ou você pode até usar $routeParams

 $routeProvider.when('/home', ...); $routeProvider.when('/home/:tab', ...); $scope.params = $routeParams; 
   

Você também pode colocar um ng-controller no nível mais alto de cada

Você pode fazer o checkout desta biblioteca para o mesmo propósito também:

http://angular-route-segment.com

Parece que você está procurando, e é muito mais simples de usar do que o roteador. Do site de demonstração :

JS:

 $routeSegmentProvider. when('https://stackoverflow.com/section1', 's1.home'). when('https://stackoverflow.com/section1/:id', 's1.itemInfo.overview'). when('https://stackoverflow.com/section2', 's2'). segment('s1', { templateUrl: 'templateshttps://stackoverflow.com/section1.html', controller: MainCtrl}). within(). segment('home', { templateUrl: 'templateshttps://stackoverflow.com/section1/home.html'}). segment('itemInfo', { templateUrl: 'templateshttps://stackoverflow.com/section1/item.html', controller: Section1ItemCtrl, dependencies: ['id']}). within(). segment('overview', { templateUrl: 'templateshttps://stackoverflow.com/section1/item/overview.html'}). 

HTML de nível superior:

  

HTML nested:

 

Section 1

Section 1 contents.

Eu também estava lutando com vistas aninhadas em Angular.

Depois que eu peguei o ui-roteador , soube que nunca voltaria à funcionalidade de roteamento padrão angular.

Aqui está um aplicativo de exemplo que usa vários níveis de exibição de aninhamento

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

Como pode ser visto, existem 4 visualizações principais (view1, view2, view3, view4) e view1 tem 3 visualizações de filhos.

Você pode usar ng-include para evitar o uso de ng-views aninhadas.

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

Minha página de índice eu uso ng-view. Então, nas minhas subpáginas, preciso ter frameworks nesteds. Eu uso ng-include. A demonstração mostra um menu suspenso. Eu substitui o meu com um link ng-click. Na function eu colocaria $ scope.template = $ scope.templates [0]; ou $ scope.template = $ scope.templates [1];

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

O roteador ui angular suporta visualizações aninhadas. Eu não usei ainda, mas parece muito promissor.

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