Legen Sie den Seitentitel mit UI-Router fest

Ich migriere meine AngularJS-basierte App, um den UI-Router anstelle des integrierten Routings zu verwenden. Ich habe es wie unten gezeigt konfiguriert

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

Wie kann ich die Variable pageTitle verwenden, um den Titel der Seite dynamisch festzulegen? Mit dem eingebauten Routing konnte ich das tun

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

und binden Sie dann die Variable in HTML, wie unten gezeigt

  

Gibt es ein ähnliches Ereignis, das ich mit dem UI-Router verbinden kann? Ich habe bemerkt, dass es ‘onEnter’ und ‘onExit’ functionen gibt, aber sie scheinen mit jedem Zustand verbunden zu sein und erfordern, dass ich Code wiederhole, um die $ rootScope Variable für jeden Zustand zu setzen.

   

Verwenden Sie $stateChangeSuccess .

Sie können es in eine Direktive einfügen:

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

Und:

  

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

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

Selbst mit $stateChangeSuccess das $timeout benötigt, damit der Verlauf korrekt ist, zumindest wenn ich mich selbst getestet habe.


Edit: Nov 24, 2014 – Erklärungsansatz:

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

Und:

 {{title}} 

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

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

Es gibt eine andere Möglichkeit, dies zu tun, indem wir die meisten Antworten bereits hier kombinieren. Ich weiß, dass dies bereits beantwortet ist, aber ich wollte zeigen, wie ich Seitentitel mit dem UI-Router dynamisch ändere.

Wenn Sie sich die ui-router- Beispielanwendung ansehen, verwenden sie den angular.run- Block, um die $ state-Variable zu $ ​​rootScope hinzuzufügen.

 // 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; }])
  • Mit dieser Definition können Sie Ihren Seitentitel dynamisch mit dem, was Sie gepostet haben, aktualisieren, aber so anpassen, dass er den definierten Status verwendet:

    Richten Sie den Status auf die gleiche Weise ein:

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

    Aber bearbeite den HTML ein bisschen …

      

    Ich kann nicht sagen, dass dies besser ist als die Antworten vor … aber es war einfacher für mich zu verstehen und zu implementieren. Hoffe das hilft jemandem!

    Das angular-ui-router-Titel- Plugin macht es einfach, den Seitentitel auf einen statischen oder dynamischen Wert basierend auf dem aktuellen Status zu aktualisieren. Es funktioniert auch korrekt mit der Browserhistorie.

    $stateChangeSuccess ist jetzt in UI-Router 1.x veraltet und standardmäßig deaktiviert. Sie müssen nun den neuen $transition .

    Eine Lösung ist nicht zu schwierig, wenn Sie einmal verstanden haben, wie $transition funktioniert. Ich habe Hilfe von @troig bekommen, um alles zu verstehen. Folgendes habe ich mir vorgenommen, um den Titel zu aktualisieren.

    Setzen Sie dies in Ihre Angular 1.6-Anwendung. Beachten Sie, dass ich die ECMAScript 6-Syntax verwende. Wenn du nicht bist, musst du zB var ändern let .

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

    Dann füge einfach eine Titelfolge zu deinem Status hinzu:

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

    Das wird die Worte “Foo Page” im Titel erscheinen lassen. (Wenn ein Zustand keinen Titel hat, wird der Seitentitel nicht aktualisiert. Es wäre eine einfache Sache, den obigen Code zu aktualisieren, um einen Standardtitel bereitzustellen, wenn ein Zustand keinen angibt.)

    Mit dem Code können Sie auch eine function für den title . Das, this zum Aufrufen der function verwendet wird, ist der Status selbst, und das eine Argument sind die Zustandsparameter, wie in diesem Beispiel:

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

    Für den URL-Pfad /bar/code/123 , der “Bar Code 123” als Seitentitel anzeigen würde. Beachten Sie, dass ich die Syntax von ECMAScript 6 verwende, um die Zeichenfolge zu formatieren und params.code extrahieren.

    Es wäre schön, wenn jemand, der Zeit hätte, etwas in eine Direktive schreiben und es für jeden veröffentlichen würde.

    $ State an $ rootscope anhängen, um sie überall in der App zu verwenden

     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 

    Ich fand diesen Weg wirklich einfach:

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

    und dann in meinem HTML so:

     

    {{ $state.current.title }}

    Aktualisieren Sie einfach window.document.title:

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

    Auf diese Weise muss “ng-app” nicht zum HTML-Tag wechseln und kann am Körper oder darunter bleiben.

    Ich benutze ngMeta , was gut funktioniert, um nicht nur Seitentitel , sondern auch Beschreibungen zu setzen. Sie können einen bestimmten Titel / eine Beschreibung für jeden Status festlegen, Standardwerte für den Fall, dass kein Titel / eine Beschreibung angegeben wird sowie Standardtitelsuffixe (z. B. “| MySiteName”) und den Autorenwert.

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

    Sie sind wirklich sehr nahe bei Ihrer ersten Antwort / Frage. Fügen Sie Ihren Titel als Datenobjekt hinzu:

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

    In Ihrer index.html binden Sie die Daten direkt an den Seitentitel:

     Failsafe text 

    Ich habe diese Kombination aus Martins und tasseKATTs Antworten gefunden – einfach und ohne Vorlagen:

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

    Warum nicht einfach:

     $window.document.title = 'Title'; 

    UPDATE: Vollständiger Richtliniencode

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

    Dann würde man auf jeder Seite einfach diese Direktive einfügen:

     

    Wenn Sie ES6 verwenden, funktioniert das gut :).

     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; 

    Vielleicht können Sie diese Direktive ausprobieren.

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

    Hier ist das Beispiel:

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

    Für aktualisierte Versionen von UI-Router 1.0.0+ ( https://ui-router.github.io/guide/ng1/migrate-to-1_0 )

    Siehe folgenden Code

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