Definir o título da página usando o roteador de interface do usuário

Estou migrando meu aplicativo baseado em AngularJS para usar o roteador-ui em vez do roteamento interno. Eu tenho configurado conforme mostrado abaixo

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

Como posso usar a variável pageTitle para definir dinamicamente o título da página? Usando o roteamento interno, eu poderia fazer

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

e depois ligar a variável em HTML como mostrado abaixo

  

Existe um evento semelhante que eu possa ligar usando o ui-roteador? Notei que existem funções ‘onEnter’ e ‘onExit’, mas elas parecem estar ligadas a cada estado e exigirão que eu repita o código para definir a variável $ rootScope para cada estado.

Use $stateChangeSuccess .

Você pode colocá-lo em uma diretiva:

 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:

  

Demonstração: http://run.plnkr.co/8tqvzlCw62Tl7t4j/#/home

Código: http://plnkr.co/edit/XO6RyBPURQFPodoFdYgX?p=preview

Mesmo com $stateChangeSuccess o $timeout foi necessário para que o histórico seja correto, pelo menos quando eu mesmo testei.


Edit: 24 de novembro de 2014 – abordagem declarativa:

 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}} 

Demonstração: http://run.plnkr.co/d4s3qBikieq8egX7/#/credits

Código: http://plnkr.co/edit/NpzQsxYGofswWQUBGthR?p=preview

Existe uma outra maneira de fazer isso, combinando a maioria das respostas aqui já. Eu sei que isso já está respondido, mas eu queria mostrar como altero dinamicamente os títulos das páginas com o roteador-ui.

Se você der uma olhada no aplicativo de amostra do ui-roteador, eles usarão o bloco .run angular para adicionar a variável $ state ao $ 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; }])
  • Com isso definido, você pode atualizar dinamicamente o título da sua página com o que você postou, mas modificou para usar o estado definido:

    Configure o estado da mesma maneira:

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

    Mas edite o html um pouco …

      

    Eu não posso dizer que isso é melhor do que as respostas antes … mas foi mais fácil para eu entender e implementar. Espero que isso ajude alguém!

    O plug – in angular-ui-router-title facilita a atualização do título da página para um valor estático ou dynamic com base no estado atual. Funciona corretamente com o histórico do navegador também.

    $stateChangeSuccess agora está obsoleto no roteador de UI 1.x e desabilitado por padrão. Agora você precisará usar o novo serviço de $transition .

    Uma solução não é muito difícil quando você entende como funciona a $transition . Eu tenho ajuda do @troig para entender tudo. Aqui está o que eu inventei para atualizar o título.

    Coloque isso na sua aplicação Angular 1.6. Note que estou usando a syntax do ECMAScript 6; se você não for, você precisará, por exemplo, alterar o let para 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; } }); 

    Em seguida, basta adicionar uma string de title ao seu estado:

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

    Isso fará com que as palavras “Foo Page” apareçam no título. (Se um estado não tiver título, o título da página não será atualizado. Seria uma coisa simples atualizar o código acima para fornecer um título padrão se um estado não indicar um.)

    O código também permite que você use uma function para title . O usado para chamar a function será o próprio estado e o argumento será os parâmetros de estado, como neste exemplo:

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

    Para o caminho de URL /bar/code/123 que mostraria “Código de Barras 123” como o título da página. Note que estou usando a syntax ECMAScript 6 para formatar a string e extrair params.code .

    Seria bom se alguém que tivesse tempo colocasse algo assim em uma diretiva e a publicasse para todo mundo usar.

    Anexando $ state a $ rootscope para usar em qualquer lugar do aplicativo.

     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 

    Eu achei isso muito fácil:

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

    e então no meu HTML assim:

     

    {{ $state.current.title }}

    Apenas atualize window.document.title:

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

    Dessa forma, o ‘ng-app’ não precisa passar para a tag HTML e pode permanecer no corpo ou menos.

    Estou usando o ngMeta , que funciona bem não só para definir o título da página, mas também as descrições. Ele permite que você defina um título / descrição específico para cada estado, padrões para quando um título / descrição não é especificado, assim como sufixos de títulos padrão (ou seja, ‘| MySiteName’) e valor de autor.

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

    Você está realmente perto de sua primeira resposta / pergunta. Adicione seu título como um object de dados:

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

    Em seu index.html, vincule os dados diretamente ao título da página:

     Failsafe text 

    Acabei com essa combinação de respostas de Martin e tasseKATT – simples e sem qualquer material relacionado a modelos:

     $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; }); }); 

    Por que não apenas:

     $window.document.title = 'Title'; 

    ATUALIZAÇÃO: Código da Diretiva Completa

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

    Então, em todas as páginas, você includeia essa diretiva:

     

    Se você estiver usando ES6, isso funciona muito bem :).

     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; 

    Talvez você possa tentar esta diretiva.

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

    Aqui está o exemplo:

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

    Para versões atualizadas do UI-Router 1.0.0+, ( https://ui-router.github.io/guide/ng1/migrate-to-1_0 )

    Consulte o seguinte código

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