411 votes

Comment changer dynamiquement d'en-tête en fonction de la vue partielle d'AngularJS ?

J'utilise ng-view pour inclure des vues partielles AngularJS, et je veux mettre à jour le titre de la page et les balises d'en-tête h1 en fonction de la vue incluse. Cependant, ces balises sont hors de portée des contrôleurs de vues partielles, et je n'arrive donc pas à comprendre comment les lier aux données définies dans les contrôleurs.

Si c'était ASP.NET MVC, vous pourriez utiliser @ViewBag pour le faire, mais je ne connais pas l'équivalent dans AngularJS. J'ai fait des recherches sur les services partagés, les événements, etc. mais je n'arrive toujours pas à le faire fonctionner. Si je peux modifier mon exemple pour qu'il fonctionne, ce sera très apprécié.

Mon HTML :

<html data-ng-app="myModule">
<head>
<!-- include js files -->
<title><!-- should changed when ng-view changes --></title>
</head>
<body>
<h1><!-- should changed when ng-view changes --></h1>

<div data-ng-view></div>

</body>
</html>

Mon JavaScript :

var myModule = angular.module('myModule', []);
myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/test1', {templateUrl: 'test1.html', controller: Test1Ctrl}).
        when('/test2', {templateUrl: 'test2.html', controller: Test2Ctrl}).
        otherwise({redirectTo: '/test1'});
}]);

function Test1Ctrl($scope, $http) { $scope.header = "Test 1"; 
                                  /* ^ how can I put this in title and h1 */ }
function Test2Ctrl($scope, $http) { $scope.header = "Test 2"; }

634voto

jkoreska Points 2815

Je viens de découvrir une façon intéressante de définir le titre de votre page si vous utilisez le routage :

JavaScript :

var myApp = angular.module('myApp', ['ngResource'])

myApp.config(
    ['$routeProvider', function($routeProvider) {
        $routeProvider.when('/', {
            title: 'Home',
            templateUrl: '/Assets/Views/Home.html',
            controller: 'HomeController'
        });
        $routeProvider.when('/Product/:id', {
            title: 'Product',
            templateUrl: '/Assets/Views/Product.html',
            controller: 'ProductController'
        });
    }]);

myApp.run(['$rootScope', function($rootScope) {
    $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
        $rootScope.title = current.$$route.title;
    });
}]);

HTML :

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="'myApp &mdash; ' + title">myApp</title>
...

Editar : à l'aide de l'outil ng-bind au lieu de boucles {{}} pour qu'ils n'apparaissent pas au chargement

342voto

Tosh Points 13477

Vous pouvez définir le contrôleur au niveau de la <html> niveau.

 <html ng-app="app" ng-controller="titleCtrl">
   <head>
     <title>{{ Page.title() }}</title>
 ...

Vous créez du service : Page et les modifier à partir des contrôleurs.

myModule.factory('Page', function() {
   var title = 'default';
   return {
     title: function() { return title; },
     setTitle: function(newTitle) { title = newTitle }
   };
});

Injecter Page et Call 'Page.setTitle()' from controllers.

Voici un exemple concret : http://plnkr.co/edit/0e7T6l

189voto

broc.seib Points 1767

Notez que vous pouvez également définir le titre directement avec javascript, c'est-à-dire,

$window.document.title = someTitleYouCreated;

Il n'y a pas de liaison de données, mais cela suffit lorsque l'on met ng-app dans le <html> est problématique. (Par exemple, l'utilisation de modèles JSP où la balise <head> est défini à un seul endroit, alors que vous avez plus d'une application).

119voto

Andy Hitchman Points 501

Déclarer ng-app sur le html fournit un champ d'application racine à la fois pour l'élément head y body .

Par conséquent, dans votre contrôleur, injectez $rootScope et lui attribuer une propriété d'en-tête :

function Test1Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 1"; }

function Test2Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 2"; }

et dans votre page :

<title ng-bind="header"></title>

43voto

Martin Atkins Points 3034

Le module angularjs-viewhead montre un mécanisme permettant de définir le titre par vue en utilisant uniquement une directive personnalisée.

Il peut être appliqué à un élément de vue existant dont le contenu est déjà le titre de la vue :

<h2 view-title>About This Site</h2>

...ou il peut être utilisé comme un élément autonome, auquel cas l'élément sera invisible dans le document rendu et ne servira qu'à définir le titre de la vue :

<view-title>About This Site</view-title>

Le contenu de cette directive est mis à disposition dans le champ d'application de la racine en tant que viewTitle Elle peut donc être utilisée sur l'élément title comme n'importe quelle autre variable :

<title ng-bind-template="{{viewTitle}} - My Site">My Site</title>

Il peut également être utilisé à n'importe quel autre endroit qui peut "voir" la lunette racine. Par exemple :

<h1>{{viewTitle}}</h1>

Cette solution permet de définir le titre via le même mécanisme que celui utilisé pour contrôler le reste de la présentation : Les templates AngularJS. Cela évite d'encombrer les contrôleurs avec cette logique de présentation. Le contrôleur doit mettre à disposition toutes les données qui seront utilisées pour informer le titre, mais c'est le modèle qui décide en dernier ressort de la manière de le présenter, et il peut utiliser l'interpolation d'expressions et les filtres pour se lier aux données de l'étendue comme d'habitude.

(Avertissement : je suis l'auteur de ce module, mais je n'y fais référence ici que dans l'espoir qu'il aidera quelqu'un d'autre à résoudre ce problème).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X