Imposta il titolo della pagina usando UI-Router

Sto migrando la mia app basata su AngularJS per usare ui-router al posto del routing integrato. L’ho configurato come mostrato di seguito

.config(function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/home'); $stateProvider .state('home', { url: '/home', templateUrl : 'views/home.html', data : { pageTitle: 'Home' } }) .state('about', { url: '/about', templateUrl : 'views/about.html', data : { pageTitle: 'About' } }) }); 

Come posso utilizzare la variabile pageTitle per impostare dynamicmente il titolo della pagina? Usando il routing integrato, potrei fare

 $rootScope.$on("$routeChangeSuccess", function(currentRoute, previousRoute){ $rootScope.pageTitle = $route.current.data.pageTitle; }); 

e quindi associare la variabile in HTML come mostrato di seguito

  

C’è un evento simile a cui posso collegarmi usando l’ui-router? Ho notato che ci sono funzioni ‘onEnter’ e ‘onExit’, ma sembrano essere legate a ciascuno stato e mi richiederà di ripetere il codice per impostare la variabile $ rootScope per ogni stato.

Usa $stateChangeSuccess .

Puoi metterlo in una direttiva:

 app.directive('updateTitle', ['$rootScope', '$timeout', function($rootScope, $timeout) { return { link: function(scope, element) { var listener = function(event, toState) { var title = 'Default Title'; if (toState.data && toState.data.pageTitle) title = toState.data.pageTitle; $timeout(function() { element.text(title); }, 0, false); }; $rootScope.$on('$stateChangeSuccess', listener); } }; } ]); 

E:

  

Demo: http://run.plnkr.co/8tqvzlCw62Tl7t4j/#/home

Codice: http://plnkr.co/edit/XO6RyBPURQFPodoFdYgX?p=preview

Anche con $stateChangeSuccess è stato necessario il $timeout affinché la cronologia sia corretta, almeno quando ho provato me stesso.


Modifica: 24 novembre 2014 – Approccio dichiarativo:

 app.directive('title', ['$rootScope', '$timeout', function($rootScope, $timeout) { return { link: function() { var listener = function(event, toState) { $timeout(function() { $rootScope.title = (toState.data && toState.data.pageTitle) ? toState.data.pageTitle : 'Default title'; }); }; $rootScope.$on('$stateChangeSuccess', listener); } }; } ]); 

E:

 {{title}} 

Demo: http://run.plnkr.co/d4s3qBikieq8egX7/#/credits

Codice: http://plnkr.co/edit/NpzQsxYGofswWQUBGthR?p=preview

C’è un altro modo per farlo combinando la maggior parte delle risposte qui già. So che è già stata data una risposta, ma volevo mostrare il modo in cui cambio dynamicmente i titoli di pagina con ui-router.

Se date un’occhiata all’app campione del router, usano il blocco angular .run per aggiungere la variabile $ state a $ rootScope.

 // It's very handy to add references to $state and $stateParams to the $rootScope // so that you can access them from any scope within your applications. // For example, 
  • // will set the
  • to active whenever 'contacts.list' or one of its // decendents is active. .run([ '$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; }])
  • Con questo definito puoi aggiornare facilmente in modo dinamico il titolo della tua pagina con quello che hai postato ma modificato per utilizzare lo stato definito:

    Imposta lo stato allo stesso modo:

     .state('home', { url: '/home', templateUrl : 'views/home.html', data : { pageTitle: 'Home' } }) 

    Ma modifica l’html un po ‘…

      

    Non posso dire che sia meglio delle risposte precedenti … ma per me è stato più facile capire e implementare. Spero che questo aiuti qualcuno!

    Il plugin angular-ui-router-title semplifica l’aggiornamento del titolo della pagina a un valore statico o dinamico basato sullo stato corrente. Funziona correttamente anche con la cronologia del browser.

    $stateChangeSuccess è ora deprecato in UI-Router 1.x e disabilitato per impostazione predefinita. Ora dovrai utilizzare il nuovo servizio di $transition .

    Una soluzione non è troppo difficile una volta capito come funziona la $transition . Ho ricevuto un aiuto da @troig per capirlo. Ecco cosa mi è venuto in mente per l’aggiornamento del titolo.

    Metti questo nella tua applicazione Angular 1.6. Si noti che sto usando la syntax ECMAScript 6; se non lo fai, avrai bisogno ad esempio di cambiare let a var .

     .run(function($transitions, $window) { $transitions.onSuccess({}, (transition) => { let title = transition.to().title; if (title) { if (title instanceof Function) { title = title.call(transition.to(), transition.params()); } $window.document.title = title; } }); 

    Quindi aggiungi una stringa di title al tuo stato:

     $stateProvider.state({ name: "foo", url: "/foo", template: "", title: "Foo Page"" }); 

    Questo farà apparire le parole “Foo Page” nel titolo. (Se uno stato non ha titolo, il titolo della pagina non verrà aggiornato. Sarebbe una semplice cosa aggiornare il codice sopra per fornire un titolo predefinito se uno stato non ne indica uno.)

    Il codice consente inoltre di utilizzare una funzione per il title . Il nome usato per chiamare la funzione sarà lo stato stesso, e l’argomento sarà i parametri di stato, come questo esempio:

     $stateProvider.state({ name: "bar", url: "/bar/{code}", template: "", title: function(params) { return `Bar Code ${params.code}`; } }); 

    Per il percorso URL /bar/code/123 che mostrerebbe “Bar Code 123” come titolo della pagina. Nota che sto usando la syntax ECMAScript 6 per formattare la stringa ed estrarre params.code .

    Sarebbe bello se qualcuno che avesse il tempo avrebbe messo qualcosa di simile in una direttiva e pubblicarla per tutti da usare.

    Albind $ state a $ rootcope per utilizzare ovunque nell’app.

     app.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) { // It's very handy to add references to $state and $stateParams to the $rootScope // so that you can access them from any scope within your applications.For example, // 
  • will set the
  • // to active whenever 'contacts.list' or one of its decendents is active. $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; } ] )
  •  about - ui-router 

    Ho trovato questo modo davvero facile:

      .state('app.staff.client', { url: '/client/mine', title: 'My Clients'}) 

    e poi nel mio HTML come questo:

     

    {{ $state.current.title }}

    Basta aggiornare window.document.title:

     .state('login', { url: '/login', templateUrl: "/Login", controller: "loginCtrl", onEnter: function($window){$window.document.title = "App Login"; } }) 

    In questo modo ‘ng-app’ non ha bisogno di passare al tag HTML e può rimanere sul corpo o inferiore.

    Sto usando ngMeta , che funziona bene non solo per impostare il titolo della pagina ma anche le descrizioni. Ti consente di impostare un titolo / descrizione specifico per ciascuno stato, i valori predefiniti per quando un titolo / descrizione non è specificato, così come i suffissi del titolo predefinito (es., ‘| MySiteName’) e il valore dell’autore.

     $stateProvider .state('home', { url: '/', templateUrl: 'views/home.html', controller: 'HomeController', meta: { 'title': 'Home', 'titleSuffix': ' | MySiteName', 'description': 'This is my home page description lorem ipsum.' }, }) 

    In realtà sei davvero vicino alla tua prima risposta / domanda. Aggiungi il tuo titolo come object dati:

     .state('home', { url: '/home', templateUrl : 'views/home.html', data : { pageTitle: 'Home' } }) 

    Nel tuo index.html associa i dati direttamente al titolo della pagina:

     Failsafe text 

    Ho finito con questa combinazione di risposte di Martin e tasseKATT – semplici e senza alcun materiale correlato a modelli:

     $rootScope.$on("$stateChangeSuccess", function (event, toState) { $timeout(function () { // Needed to ensure the title is changed *after* the url so that history entries are correct. $window.document.title = toState.name; }); }); 

    Perché non solo:

     $window.document.title = 'Title'; 

    AGGIORNAMENTO: codice di piena direttiva

     var DIRECTIVE = 'yourPageTitle'; yourPageTitle.$inject = ['$window']; function yourPageTitle($window: ng.IWindowService): ng.IDirective { return { link: (scope, element, attrs) => { attrs.$observe(DIRECTIVE, (value: string) => { $window.document.title = value; }); } } } directive(DIRECTIVE, yourPageTitle); 

    Quindi in ogni pagina devi semplicemente includere questa direttiva:

     

    Se stai usando ES6, funziona bene :).

     class PageTitle { constructor($compile, $timeout) { this.restrict = 'A'; this._$compile = $compile; this.$timeout = $timeout; } compile(element) { return this.link.bind(this); } link(scope, element, attrs, controller) { let defaultTitle = attrs.pageTitle ? attrs.pageTitle : "My Awesome Sauce Site"; let listener = function(event, toState) { let title = defaultTitle; if (toState.data && toState.data.title) title = toState.data.title + ' | ' + title; $('html head title').text(title); }; scope.$on('$stateChangeStart', listener); } } export function directiveFactory($compile) { return new PageTitle($compile); } directiveFactory.injections = ['$compile', '$timeout']; export default PageTitle; 

    Forse puoi provare questa direttiva.

    https://github.com/afeiship/angular-dynamic-title

    Ecco l’esempio:

    html:

     Title State1 page State2 page 

    javascript:

     var TestModule = angular.module('TestApp', ['ui.router','nx.widget']) .config(function ($stateProvider, $urlRouterProvider) { // // For any unmatched url, redirect to /state1 $urlRouterProvider.otherwise("/state1"); // // Now set up the states $stateProvider .state('state1', { url: "/state1", templateUrl: "partials/state1.html", data:{ pageTitle:'State1 page title11111' } }) .state('state2', { url: "/state2", templateUrl: "partials/state2.html",data:{ pageTitle:'State2 page title222222' } }); }) .controller('MainCtrl', function ($scope) { console.log('initial ctrl!'); }); 

    Per le versioni aggiornate di UI-Router 1.0.0+, ( https://ui-router.github.io/guide/ng1/migrate-to-1_0 )

    Fare riferimento al seguente codice

     app.directive('pageTitle', [ '$rootScope', '$timeout', '$transitions', function($rootScope, $timeout,$transitions) { return { restrict: 'A', link: function() { var listener = function($transitions) { var default_title = "DEFAULT_TITLE"; $timeout(function() { $rootScope.page_title = ($transitions.$to().data && $transitions.$to().data.pageTitle) ? default_title + ' - ' + $transitions.$to().data.pageTitle : default_title; }); }; $transitions.onSuccess({ }, listener); } } } ])