Angular UI-Router Comment créer un état “layout”?

Étant donné un fichier HTML comme celui-ci:

 

Comment créer un état de mise en page remplissant le “header” avec un modèle d’en-tête, le pied de page avec un modèle de pied de page, puis autoriser les états enfants à remplir la vue d’interface utilisateur vide?

Je suppose que l’interface utilisateur vide pourrait aussi être nommée quelque chose comme ui-view = “main”.

L’une des méthodes consiste à créer un état «racine» global. Ainsi, chaque État sera son enfant. Comme root.pages, root.pages.edit, root.settings, etc. Vous pouvez ensuite fournir des modèles par défaut pour l’en-tête et le pied de page.

Une autre façon, que j’utilise personnellement, est d’utiliser ng-include pour l’en-tête et le pied de page.

   

Btw. J’utilise un contrôleur distinct dans header.tpl.html, qui est un enfant de AppCtrl principal.

  

Essayez ceci, pratiquement votre en-tête et votre pied de page sont des modèles statiques mais vous pouvez append les contrôleurs au cas où vous auriez besoin d’y append des fonctionnalités dynamics. L’en-tête et le pied de page seront inclus par défaut. :

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

Edit: pour moi, le meilleur endroit pour définir les vues devrait être dans index.html et quelque chose comme ce code:

 

Il existe en fait un moyen très simple de le faire.

1. Créez un état de mise en page

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

2. Utilisez un état d’affichage non nommé à l’intérieur de la mise en page

  

3. Créez un état d’affichage

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

4. Utiliser l’état de mise en page nommé en tant qu’état racine

   

Sur la base de la réponse de Jack.the.ripper, j’ai créé cette solution.

Casus: J’ai une légère variation que je veux en fait 2 mises en page. Un public et un privé. Dans Meteor avec Blaze et Iron Router, il y avait une bonne solution que vous pouviez simplement définir quel modèle maître serait utilisé pour un itinéraire donné. Cela, je suis maintenant capable de mettre en place grâce à Jack!

NOTE: Le code sera en Jade et Coffee et c’est un projet Meteor + Angular. Utilisez http://js2.coffee/ pour convertir en 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 '/' ) 

C’est le fichier d’index dans lequel la vue d’application est définie pour utiliser l’état abstrait défini dans le routeur.

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

Ensuite, la mise en page privée avec sa vue conteneur.

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

et enfin la mise en page publique avec sa vue conteneur

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

Avec cette configuration, je peux configurer la page de connexion pour utiliser la présentation publique abstraite en indiquant dans la vue de cette route qu’elle doit utiliser les vues container @ public, ce qui signifie depuis la vue Public, utiliser la vue Container. Dans cette vue, chargez le login.html.

Même chose pour la page d’accueil, celle-ci charge le conteneur @ private, ce qui signifie la vue Container de la vue privée.

Cela semble fonctionner comme un charme.

Merci beaucoup Jack, et aussi l’auteur de la réponse sur Angular UI Router – États nesteds avec plusieurs mises en page, ce qui m’a aidé à trouver la solution finale.

À votre santé

Semblable à la façon de jack.the.ripper, vous pouvez également le faire comme il fonctionne pour moi.

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

Dans notre index.html nous aurons seulement une

Le master.html ressemblera à

 

Pourquoi j’ai choisi cette approche, c’est que je n’ai pas besoin de créer un contrôleur global distinct, et mon mainController sera le contrôleur global.

Au lieu d’utiliser des routes du tout pour l’en-tête et le pied de page, j’utiliserais des composants angulars maintenant qu’ils sont disponibles en 1.5x.

C’est beaucoup plus flexible et vous n’avez pas à gérer root.whatever ou ngInclude. Je vais plus en détail ici: https://stackoverflow.com/a/41093339/2416007 , mais essentiellement vous:

1. Créer un composant

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

2. Ajoutez-le à votre page index.html ou similaire

  

3. Même chose pour le pied de page

  

4. Le résultat dans le corps est