Router UI angular ¿Cómo crear un estado “diseño”?

Dado un archivo HTML como ese:

 

¿Cómo se podría crear un estado de disposición que llene el “encabezado” con una plantilla de encabezado, el pie de página con una plantilla de pie de página, y luego permitir que los estados secundarios llenen la vista de usuario vacía?

Supongo que el ui-view vacío también podría llamarse algo así como ui-view = “main”.

Una forma es crear un estado global de ‘raíz’. Entonces, cada estado será su hijo. Como root.pages, root.pages.edit, root.settings, etc. Luego puede proporcionar plantillas predeterminadas para encabezado y pie de página.

Otra forma, enfoque diferente, que uso personalmente, es usar ng-include para encabezado y pie de página.

   

Por cierto. Uso un controlador independiente en header.tpl.html, que es un elemento secundario de la AppCtrl principal .:

  

intente esto, prácticamente su encabezado y pie de página son plantillas estáticas, pero puede agregar los controladores en caso de que necesite agregar alguna funcionalidad dinámica, el encabezado y el pie de página se incluirán de manera predeterminada ya que la ruta es ”, así que pruébelo :

  app.config(['$stateProvider', function($stateProvider){ $stateProvider .state('root',{ url: '', abstract: true, views: { 'header': { templateUrl: 'header.html', controller: 'HeaderCtrl' }, 'footer':{ templateUrl: 'footer.html', controller: 'FooterCtrl' } } }) .state('root.home', { url: '/', views: { 'container@': { templateUrl: 'homePage.html' } } }) .state('root.other', { url: '/other', views: { 'container@': { templateUrl: 'other.html' } } }); }]); 

Editar: para mí, el mejor lugar para establecer las vistas debe estar en el index.html y algo así como este código:

 

De hecho, hay una manera muy fácil de hacerlo.

1. Crea un estado de diseño

 $stateProvider .state('master', { abstract: true, views: { layout: { templateUrl: '/layouts/master.html', } } }); 

2. Usar estado de vista sin nombre dentro del diseño

  

3. Crear un estado de vista

 $stateProvider .state('home', { url: '/', templateUrl: '/views/home.html', parent: 'master', }); 

4. Utilice el estado de diseño con nombre como estado raíz

   

Basado en la respuesta de Jack.the.ripper, creé esta solución.

Casus: Tengo una ligera variación de que realmente quiero 2 diseños. Un público y un privado. En Meteor with Blaze y Iron Router, había una buena solución que podía definir qué plantilla maestra se utilizará para una determinada ruta. ¡Esto lo he podido configurar gracias a Jack!

NOTA: El código estará en Jade and Coffee y es un proyecto Meteor + Angular. Usa http://js2.coffee/ para convertir a Javascript.

 # the ROUTER part # angular.module( 'myApp' ).config( ( $urlRouterProvider, $stateProvider, $locationProvider ) -> $locationProvider.html5Mode true $stateProvider .state( 'private', url: '' abstract: true views: 'app': templateUrl: 'client/views/layouts/privateLayout.html' ) .state( 'public', url: '' abstract: true views: 'app': templateUrl: 'client/views/layouts/publicLayout.html' ) .state( 'private.home', url: '/' views: "container@private": templateUrl: 'client/views/home/home.html' ) .state( 'public.login', url: '/login' views: "container@public": templateUrl: 'client/views/session/login.html' ) $urlRouterProvider.otherwise '/' ) 

Este es el archivo de índice donde se define la vista de la aplicación que utilizará el estado abstracto definido en el enrutador.

 head meta(name="viewport" content="width=device-width, initial-scale=1") base(href="/") body(layout="column") div(ui-view="app" layout="column" flex) 

Luego, el diseño privado con su vista de contenedor.

 div(layout="column" flex) div(ng-controller="AppCtrl" layout="row" flex) //- some private Layout stuff happening here.... md-content(flex layout-padding) div(ui-view="container" layout="column") 

y finalmente el diseño público con su vista de contenedor

 div.public-layout(layout="column" flex) div(ui-view="container" layout="column" flex) 

Con esta configuración, puedo configurar la página de inicio de sesión para usar el diseño público abstracto indicando en la vista de esta ruta que debe usar vistas contenedor @ público, es decir, desde la vista Pública, use la vista Contenedor. En esta vista cargue el archivo login.html.

Lo mismo ocurre con la página de inicio, esta carga el contenedor @ private que significa la vista del contenedor de la vista privada.

Esto parece funcionar como un encanto.

Muchas gracias Jack, y también el autor de la respuesta en Angular UI Router – Anidados Estados con múltiples diseños que me ayudaron a llegar a la solución final.

Aclamaciones

Al igual que en el camino de jack.the.ripper, también podrías hacerlo de la forma en que funciona para mí.

 app.config(function($stateProvider, $urlRouterProvider) { $stateProvider .state('root', { /* The Root State */ views: { '': { abstract: true, templateUrl: 'master.html', controller: 'mainController' }, 'header@root': { templateUrl: 'header.html', controller: 'headerController', }, 'footer@root': { templateUrl: 'footer.html', controller: 'footerController' }, }, }) .state('root.index', { /* The Index State */ url: '/', views: { 'content': { templateUrl: 'index.html', controller: 'indexController' } }, .state('root.other', { /* The Other State */ url: '/', views: { 'content': { templateUrl: 'other.html', controller: 'otherController' } }, }); }); 

En nuestro index.html solo tendremos una

El master.html se verá como

 

Por qué elegí este enfoque, es que no tengo que crear un controlador global separado, y mi mainController será el controlador global.

En lugar de usar rutas para el encabezado y el pie de página, usaría componentes angulares ahora que están disponibles en 1.5x.

Es mucho más flexible y no tiene que tratar con root.whatever o ngInclude. Lo analizo con más detalle aquí: https://stackoverflow.com/a/41093339/2416007 , pero esencialmente usted:

1. Crear componente

 (function () { 'use strict'; angular .module('layout') .component('layoutHeader', { templateUrl: 'layout/header.html', bindings: {}, controller: Controller }); Controller.$inject = []; function Controller() { var ctrl = this; initialize(); //////////////////// function initialize(){ } } }()); 

2. Agréguelo a su página index.html o similar

  

3. Lo mismo para el pie de página

  

4. El resultado en el cuerpo es