J'utilise ng-view pour inclure les vues partielles AngularJS et je souhaite mettre à jour le titre de la page et les balises d'en-tête h1 en fonction de la vue incluse. Cependant, ceux-ci sont hors de portée des contrôleurs de vue partielle, et je ne peux donc pas comprendre comment les lier à l'ensemble de données dans les contrôleurs.
Si c'était ASP.NET MVC, vous pourriez utiliser @ViewBag pour cela, mais je ne connais pas l'équivalent dans AngularJS. J'ai cherché des services partagés, des événements, etc., mais je n'arrive toujours pas à le faire fonctionner. Toute façon de modifier mon exemple afin qu'il fonctionne serait très appréciée.
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"; }
Réponses:
Vous pouvez définir le contrôleur au
<html>
niveau.Vous créez le service:
Page
et modifiez à partir des contrôleurs.Injectez
Page
et appelez «Page.setTitle ()» à partir des contrôleurs.Voici l'exemple concret: http://plnkr.co/edit/0e7T6l
la source
$rootScope
lieu de créer un contrôleur supplémentaire.Je viens de découvrir une belle façon de définir le titre de votre page si vous utilisez le routage:
JavaScript:
HTML:
Modifier : utiliser l'
ng-bind
attribut au lieu de curlies{{}}
pour qu'ils ne s'affichent pas à la chargela source
title = "Blog"
mais pastitle = '{{"Blog post " + post.title}}'
.current.title
aussicurrent.$route
dans l'ancien code et cela fonctionnait. Avec la mise à niveau, le double $ sur l'itinéraire est nécessaire.current.$$route
'/Product/:id'
. Existe-t-il un moyen d'avoir la:id
valeur avec cette méthode? J'ai essayétitle: function(params){return params.id;}
mais ça ne marche pas ... Peut-être en utilisantresolve
?Notez que vous pouvez également définir le titre directement avec javascript, c'est-à-dire,
Cela n'a pas de liaison de données, mais cela suffit lorsque la mise
ng-app
en place de la<html>
balise est problématique. (Par exemple, en utilisant des modèles JSP où<head>
est défini exactement à un endroit, mais vous avez plus d'une application.)la source
La déclaration
ng-app
sur l'html
élément fournit une portée racine à la fois pourhead
etbody
.Par conséquent, dans votre contrôleur, injectez
$rootScope
et définissez une propriété d'en-tête:et dans votre page:
la source
document.title = "App"
;Le module angularjs-viewhead montre un mécanisme pour 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:
... ou il peut être utilisé comme élément autonome, auquel cas l'élément sera invisible dans le document rendu et ne sera utilisé que pour définir le titre de la vue:
Le contenu de cette directive est rendu disponible dans la portée racine en tant que
viewTitle
, il peut donc être utilisé sur l'élément title comme n'importe quelle autre variable:Il peut également être utilisé à tout autre endroit qui peut "voir" la portée racine. Par exemple:
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 modèles AngularJS. Cela évite d'avoir à encombrer les contrôleurs avec cette logique de présentation. Le responsable du traitement doit mettre à disposition toutes les données qui seront utilisées pour informer le titre, mais le modèle prend la décision finale sur la façon de le présenter, et peut utiliser l'interpolation d'expression et des filtres pour se lier aux données de portée comme d'habitude.
(Avertissement: je suis l'auteur de ce module, mais je ne le référence ici que dans l'espoir qu'il aidera quelqu'un d'autre à résoudre ce problème.)
la source
Voici une solution adaptée qui fonctionne pour moi qui ne nécessite pas d'injection de $ rootScope dans les contrôleurs pour définir les titres de page spécifiques aux ressources.
Dans le modèle maître:
Dans la configuration de routage:
Et dans le bloc d'exécution:
Enfin dans le contrôleur:
la source
$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
this.title = title.replace('<', '<').replace('>', '>').replace(' & ', ' & ') + ' | Site Name';
La solution de jkoreska est parfaite si vous connaissez les titres à l'avance, mais vous devrez peut-être définir le titre en fonction des données que vous obtenez d'une ressource, etc.
Ma solution nécessite un seul service. Puisque le rootScope est la base de tous les éléments DOM, nous n'avons pas besoin de mettre un contrôleur sur l'élément html comme quelqu'un mentionné
Page.js
index.jade
Tous les contrôleurs qui doivent changer de titre
la source
{{title}}
utilisez plutôtng-bind='title'
ng-bind
empêche la syntaxe pré-interpolée de s'afficher avant que le titre ne soit réellement évalué. +100Une manière propre qui permet de définir dynamiquement le titre ou la méta description. Par exemple, j'utilise ui-router mais vous pouvez utiliser ngRoute de la même manière.
HTML:
la source
Alternativement, si vous utilisez ui-router :
index.html
Acheminement
la source
ui-router
jour l'URL et le contenu en fonction de mon état et je ne reçois aucune erreur ni avertissement, mais je n'arrive pas à accéder à aucune partie de l'objet de configuration d'état via$state.current.[...]
. Quelle versionui-router
avez-vous utilisée pour ce faire?Solution personnalisée basée sur les événements
Voici une autre approche qui n'a pas été mentionnée par les autres ici (au moment d'écrire ces lignes).
Vous pouvez utiliser des événements personnalisés comme ceci:
Cette approche a l'avantage de ne pas nécessiter l'écriture de services supplémentaires, puis d'être injectée dans chaque contrôleur qui doit définir le titre, et n'utilise pas (ab) le
$rootScope
. Il vous permet également de définir un titre dynamique (comme dans l'exemple de code), ce qui n'est pas possible en utilisant des attributs de données personnalisés sur l'objet de configuration du routeur (pour autant que je sache au moins).la source
Pour les scénarios où vous n'avez pas de ngApp contenant la
title
balise, injectez simplement un service aux contrôleurs qui doivent définir le titre de la fenêtre.Exemple de travail ... http://jsfiddle.net/8m379/1/
la source
Si vous ne contrôlez pas l'élément de titre (comme le formulaire Web asp.net), voici quelque chose que vous pouvez utiliser
la source
Manière simple et sale en utilisant
$rootScope
:Dans vos contrôleurs, lorsque vous avez les données nécessaires pour créer le titre, faites:
la source
Aucune de ces réponses ne semblait assez intuitive, j'ai donc créé une petite directive pour ce faire. De cette façon, vous pouvez déclarer le titre dans la page, où on le ferait normalement, et lui permettre d'être dynamique également.
Vous devrez bien sûr changer le nom du module pour qu'il corresponde au vôtre.
Pour l'utiliser, jetez simplement ceci dans votre vue, tout comme vous le feriez pour une
<title>
balise régulière :Vous pouvez également simplement inclure du texte brut si vous n'en avez pas besoin par dynamique:
Alternativement, vous pouvez utiliser un attribut, pour le rendre plus convivial pour IE:
Vous pouvez mettre le texte que vous voulez dans la balise bien sûr, y compris le code angulaire. Dans cet exemple, il recherchera
$scope.titleText
le contrôleur dans lequel se trouve actuellement la balise de titre personnalisé.Assurez-vous simplement que vous n'avez pas plusieurs balises de titre de page sur votre page, sinon elles s'encombreront.
Exemple de Plunker ici http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV . Vous devrez télécharger le zip et l'exécuter localement afin de voir le changement de titre.
la source
html
. Dans ma directive, j'injecte également unepageTitlePrefix
constante facultative .Solution simpliste pour angular-ui-router:
HTML:
App.js> bloc myApp.config
App.js> myApp.run
la source
Voici une autre façon de modifier le titre. Peut-être pas aussi évolutif qu'une fonction d'usine (qui pourrait en théorie gérer un nombre illimité de pages) mais il était plus facile pour moi de comprendre:
Dans mon index.html j'ai commencé comme ceci:
Ensuite, j'ai fait un partiel appelé "nav.html":
Ensuite, je suis retourné à "index.html" et j'ai ajouté le nav.html en utilisant ng-include et la vue ng pour mes partiels:
Remarquez ce ng-manteau? Cela n'a rien à voir avec cette réponse, mais elle masque la page jusqu'à ce qu'elle soit terminée, une belle touche :) Apprenez comment ici: Angularjs - les éléments ng-cloak / ng-show clignotent
Voici le module de base. Je l'ai mis dans un fichier appelé "app.js":
Si vous regardez vers la fin du module, vous verrez que j'ai une page de détail de créature basée sur: id. C'est un partiel qui est utilisé à partir de la page Crispy Critters. [Corny, je sais - c'est peut-être un site qui célèbre toutes sortes de pépites de poulet;) Quoi qu'il en soit, vous pouvez mettre à jour le titre lorsqu'un utilisateur clique sur n'importe quel lien, donc dans ma page principale de Crispy Critters qui mène à la page de détail de la créature, c'est là que la mise à jour $ root.title irait, comme vous l'avez vu dans le nav.html ci-dessus:
Désolé si venteux mais je préfère un article qui donne suffisamment de détails pour le mettre en route. Notez que la page d'exemple dans les documents AngularJS est obsolète et montre une version 0.9 de ng-bind-template. Vous pouvez voir que ce n'est pas si différent.
Après coup: vous le savez, mais il est là pour quelqu'un d'autre; en bas de l'index.html, il faut inclure app.js avec le module:
la source
Quand j'ai dû résoudre ce problème, je ne pouvais pas placer le tag
ng-app
sur la pagehtml
, alors je l'ai résolu avec un service:la source
Solution événementielle personnalisée inspirée de Michael Bromley
Je n'ai pas pu le faire fonctionner avec $ scope, j'ai donc essayé avec rootScope, peut-être un peu plus sale ... (surtout si vous faites un rafraîchissement sur la page qui n'enregistre pas l'événement)
Mais j'aime vraiment l'idée de la façon dont les choses sont lâchement couplées.
J'utilise angularjs 1.6.9
index.run.js
anyController.controller.js
index.html
Ça marche pour moi :)
la source
Alors que d'autres peuvent avoir de meilleures méthodes, j'ai pu utiliser $ rootScope dans mes contrôleurs, car chacune de mes vues / modèles a un contrôleur distinct. Vous devrez injecter $ rootScope dans chaque contrôleur. Bien que cela ne soit pas idéal, cela fonctionne pour moi, alors j'ai pensé que je devais le transmettre. Si vous inspectez la page, il ajoute la liaison ng à la balise de titre.
Exemple de contrôleur:
Exemple d'en-tête Index.html:
Vous pouvez également définir le pageTitle et la pageDescription sur des valeurs dynamiques, telles que le renvoi de données à partir d'un appel REST:
Encore une fois, d'autres peuvent avoir de meilleures idées sur la façon d'aborder cela, mais comme j'utilise un pré-rendu, mes besoins sont satisfaits.
la source
Merci à tosh shimayama pour sa solution.
Je pensais que ce n'était pas si propre de mettre un service directement dans le
$scope
, alors voici ma légère variation à ce sujet: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWsLe contrôleur (qui dans la réponse d'origine me semblait un peu trop stupide) crée un objet ActionBar, et celui-ci est inséré dans $ scope.
L'objet est chargé d'interroger réellement le service. Il masque également la portée $ l'appel pour définir l'URL du modèle, qui est à la place disponible pour d'autres contrôleurs pour définir l'URL.
la source
M. Hash a eu la meilleure réponse jusqu'à présent, mais la solution ci-dessous la rend idéale (pour moi) en ajoutant les avantages suivants:
Dans le routeur:
Dans le bloc d'exécution:
la source
La solution meilleure et dynamique que j'ai trouvée consiste à utiliser $ watch pour suivre les modifications des variables, puis à mettre à jour le titre.
la source