UI- राउटर का उपयोग करके पृष्ठ का शीर्षक सेट करें


101

मैं रूटिंग में निर्मित के बजाय ui- राउटर का उपयोग करने के लिए अपने AngularJS आधारित ऐप को माइग्रेट कर रहा हूं। मैंने इसे नीचे दिखाए अनुसार कॉन्फ़िगर किया है

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

मैं पृष्ठ के शीर्षक को गतिशील रूप से सेट करने के लिए पेजटाइट चर का उपयोग कैसे कर सकता हूं? अंतर्निहित रूटिंग का उपयोग करके, मैं कर सकता था

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

और फिर नीचे दिखाए अनुसार HTML में चर को बांधें

<title ng-bind="$root.pageTitle"></title>

क्या ऐसी ही कोई घटना है जिसे मैं यूआई-राउटर का उपयोग करने के लिए हुक कर सकता हूं? मैंने देखा कि 'onEnter' और 'onExit' फ़ंक्शन हैं, लेकिन वे प्रत्येक राज्य से बंधे हुए प्रतीत होते हैं और मुझे प्रत्येक राज्य के लिए $ rootScope चर सेट करने के लिए कोड दोहराने की आवश्यकता होगी।


3
एक $ StateChangeSuccess घटना है।
जेराद

जवाबों:


108

का उपयोग करें $stateChangeSuccess

आप इसे एक निर्देश में रख सकते हैं:

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

तथा:

<title update-title></title>

डेमो: http://run.plnkr.co/8tqvzlCw62Tl7t4j/#/home

कोड: http://plnkr.co/edit/XO6RyBPURQFPodoFdYgX?p ।preview

यहां तक कि साथ के लिए इतिहास सही होने की जरूरत किया गया है, कम से कम जब मैं अपने आप को परीक्षण किया है।$stateChangeSuccess$timeout


संपादित करें: 24 नवंबर, 2014 - घोषणात्मक दृष्टिकोण:

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

तथा:

<title>{{title}}</title>

डेमो: http://run.plnkr.co/d4s3qBikieq8egX7/#/credits

कोड: http://plnkr.co/edit/NpzQsxYGofswWQUBGthR?f=view


शानदार बहुत बढ़िया। यह किसी भी आसान नहीं मिल सकता है
मैथ्यू Harwood

3
यह उदाहरण भी इतिहास के साथ ठीक से काम नहीं करता है (कम से कम क्रोम 37 में)। यदि आप विभिन्न राज्यों के बीच जाते हैं, तो अपने इतिहास को देखें, इतिहास आइटम का शीर्षक पिछले पृष्ठ का मूल्य होगा। यदि आप पेज 1 -> पेज 2 -> पेज 3 पर जाते हैं, तो इतिहास देखें, पेज 2 का यूआरएल पेज 1 के शीर्षक के साथ मिलान किया जाएगा।
jkjustjoshing

2
वास्तव में, यह काफी सटीक नहीं है। URL हैश बदलने से पहले पृष्ठ का शीर्षक बदल जाता है, इसलिए ब्राउज़र सोचता है कि नया शीर्षक पुराने पृष्ठ के लिए है। पीछे का बटन इतिहास 1 पेज का है। element.text(title)$ टाइमआउट में कॉल लपेटना मेरे लिए काम कर गया। मूल पोस्ट का संपादन।
jkjustjoshing

3
यह काम नहीं करेगा यदि शीर्षक कुछ url paramaters के आधार पर गतिशील होने की आवश्यकता है।
कुशाग्र गौर

10
@ कुशाग्रगौर यदि शीर्षक को $ StateParams के आधार पर गतिशील होने की आवश्यकता है, तो आप resolveइसे उत्पन्न करने के लिए किसी फ़ंक्शन का उपयोग कर सकते हैं , फिर $ StateChangeSuccess इवेंट के दौरान "हल किए गए" मान पर पहुँचें $state.$current.locals.resolve.$$values.NAME_OF_RESOLVE_FUNCTION:।
क्लॉस कॉनराड

91

यहाँ पहले से ही अधिकांश उत्तरों को मिलाकर ऐसा करने का एक और तरीका है। मुझे पता है कि यह पहले से ही उत्तर दिया गया है लेकिन मैं जिस तरह से ui- राउटर के साथ पृष्ठ के शीर्षक को गतिशील रूप से बदलना चाहता था।

यदि आप यूआई-राउटर के नमूना ऐप पर एक नज़र डालते हैं , तो वे $ r में $ rSSope पर स्टेट स्टेट वैरिएबल को जोड़ने के लिए कोणीय .run ब्लॉक का उपयोग करते हैं ।

// 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, <li ng-class="{ active: $state.includes('contacts.list') }"> 
// will set the <li> 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;
}])

इस परिभाषित के साथ आप तब आसानी से गतिशील रूप से अपने पृष्ठ के शीर्षक को अपडेट कर सकते हैं जो आपने पोस्ट किया है लेकिन परिभाषित राज्य का उपयोग करने के लिए संशोधित किया है:

राज्य को उसी तरह सेट करें:

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

लेकिन html को थोड़ा एडिट करें ...

<title ng-bind="$state.current.data.pageTitle"></title>

मैं यह नहीं कह सकता कि यह पहले के जवाबों से बेहतर है ... लेकिन मुझे समझना और लागू करना आसान था। आशा है कि यह किसी की मदद करता है!


3
स्वीकृत उत्तर की तुलना में अधिक घोषणात्मक। यह मुझे पंसद है!
एंडी तजाहोनो

3
यकीन नहीं होता कि मैं पूरे रूट की वस्तु को $ $ रूटस्कॉप में सिर्फ पेज के शीर्षक के लिए पसंद करूंगा ...
करेरा

मुझे यकीन नहीं है कि जहां $ स्कोप ऑब्जेक्ट को संदर्भित किया जा रहा है @ JessúsCarrera
cwbutler

अप्स, सॉरी मेरा मतलब $ राज्य की वस्तु है
जेसुअस करेरा

4
बस की पुष्टि करने के github.com/angular-ui/ui-router/wiki/Quick-Reference भी सेटिंग की सिफारिश की $stateऔर $stateParamsपर $rootScopeभीतर से run
मार्क पीटरसन

17

कोणीय-ui-रूटर-शीर्षक प्लगइन यह आसान एक करने के लिए पृष्ठ का शीर्षक अद्यतन करने के लिए बनाता है स्थिर या गतिशील वर्तमान स्थिति के आधार मूल्य। यह ब्राउज़र इतिहास के साथ भी सही ढंग से काम करता है।


यह आगे बढ़ने का सबसे अच्छा समाधान प्रतीत होता है। मैंने इस पृष्ठ पर कुछ अन्य समाधानों का उपयोग करते हुए ब्राउज़र इतिहास के साथ कई विसंगतियों पर ध्यान दिया है।

कोणीय-यूआई-राउटर-शीर्षक सबसे अच्छा समाधान लगता है। सबसे अधिक यह परेशानी मुक्त है! धन्यवाद Stepan
डेरियो

यह एक बहुत छोटे स्रोत फ़ाइल है।
टायलर कोलियर

15

$stateChangeSuccessअब UI-Router 1.x में अपग्रेड किया गया है और डिफ़ॉल्ट रूप से अक्षम है। अब आपको नई $transitionसेवा का उपयोग करना होगा ।

एक बार जब आप समझते हैं कि कैसे $transitionकाम करता है, तो समाधान बहुत मुश्किल नहीं है । मुझे यह सब समझने में @troig से कुछ मदद मिली । शीर्षक को अपडेट करने के लिए मैं यहां आया हूं।

इसे अपने कोणीय 1.6 अनुप्रयोग में रखें। ध्यान दें कि मैं ECMAScript 6 सिंटैक्स का उपयोग कर रहा हूं; यदि आप नहीं कर रहे हैं, तो आप जैसे जरूरत को बदलने के लिए करता हूँ letकरने के लिए 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;
        }
    });

फिर बस titleअपने राज्य में एक स्ट्रिंग जोड़ें :

$stateProvider.state({
    name: "foo",
    url: "/foo",
    template: "<foo-widget layout='row'/>",
    title: "Foo Page""
});

इससे शीर्षक में "फू पेज" शब्द दिखाई देंगे। (यदि किसी राज्य का कोई शीर्षक नहीं है, तो पृष्ठ का शीर्षक अपडेट नहीं किया जाएगा। यदि कोई राज्य एक संकेत नहीं देता है, तो डिफ़ॉल्ट शीर्षक प्रदान करने के लिए ऊपर दिए गए कोड को अपडेट करना एक साधारण बात होगी।)

कोड आपको एक फ़ंक्शन का उपयोग करने की अनुमति भी देता है titlethisसमारोह कॉल करने के लिए राज्य में ही किया जाएगा इस्तेमाल किया, और एक तर्क राज्य पैरामीटर, इस उदाहरण की तरह हो जाएगा:

$stateProvider.state({
    name: "bar",
    url: "/bar/{code}",
    template: "<bar-widget code='{{code}}' layout='row'/>",
    title: function(params) {
        return `Bar Code ${params.code}`;
    }
});

URL पथ के लिए /bar/code/123जो पृष्ठ शीर्षक के रूप में "बार कोड 123" दिखाएगा। ध्यान दें कि मैं स्ट्रिंग और अर्क को प्रारूपित करने के लिए ECMAScript 6 सिंटैक्स का उपयोग कर रहा हूं params.code

यह अच्छा होगा यदि किसी के पास समय हो, जो किसी निर्देश में कुछ इस तरह रखे और सभी के उपयोग के लिए प्रकाशित करे।


dataकस्टम कुंजियों के लिए ऑब्जेक्ट का उपयोग करें । इंटरफ़ेस titleपर मौजूद नहीं है StateDeclaration
गौरी

5

ऐप में कहीं भी उपयोग करने के लिए $ राज्य को $ rootcope में संलग्न करना।

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,
        // <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
        // to active whenever 'contacts.list' or one of its decendents is active.
        $rootScope.$state = $state;
        $rootScope.$stateParams = $stateParams;
    }
  ]
)
<title ng-bind="$state.current.name + ' - ui-router'">about - ui-router</title>


1
प्रत्येक राज्य में शीर्षक जोड़ने के साथ यह संयुक्त। सही काम करता है।
WCByrne


5

बस window.document.title को अपडेट करें:

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

इस तरह 'एनजी-ऐप' को एचटीएमएल टैग तक जाने की जरूरत नहीं है और यह शरीर या निचले हिस्से पर रह सकता है।


1
यह सबसे अच्छा जवाब क्यों नहीं है? = /
रेक्स

3

मैं ngMeta का उपयोग कर रहा हूं , जो न केवल पृष्ठ शीर्षक बल्कि वर्णन के लिए भी अच्छा काम करता है। यह आपको प्रत्येक राज्य के लिए एक विशिष्ट शीर्षक / विवरण निर्धारित करने देता है, जब एक शीर्षक / विवरण निर्दिष्ट नहीं किया जाता है, साथ ही डिफ़ॉल्ट शीर्षक प्रत्यय (यानी, '| MySiteName') और लेखक का मान।

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

2

आप वास्तव में अपने पहले उत्तर / प्रश्न के साथ वास्तव में करीब हैं। डेटा ऑब्जेक्ट के रूप में अपना शीर्षक जोड़ें:

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

अपने index.html में, डेटा को सीधे पेज शीर्षक पर बाँधें:

<title data-ng-bind="$state.current.data.pageTitle + ' - Optional text'">Failsafe text</title>

1

मैंने मार्टिन के इस संयोजन और tasseKATT के उत्तरों के साथ समाप्त किया - सरल और बिना किसी टेम्पलेट संबंधित सामग्री के:

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

यदि कोई टेम्प्लेट से संबंधित सामग्री नहीं है, तो एक नए देव को कैसे पता चलेगा कि शीर्षक को बिना पूछे कैसे बदला जा रहा है?
ton.yeung

यदि आप $ window.document.title का उपयोग करते हैं, तो $ timeout बेकार है। मैं सिर्फ $ टाइमआउट और $ डाइजेस्ट साइकल से छुटकारा पाने के लिए इस हैकिश का अनुसरण कर रहा हूं :)
व्हिशर

1

सिर्फ क्यों नहीं:

$window.document.title = 'Title';

अद्यतन: पूर्ण निर्देश कोड

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

फिर हर पृष्ठ में आप इस निर्देश को शामिल करेंगे:

<section
    your-page-title="{{'somePage' | translate}}">

संभावित रूप से यह पता लगाना बहुत कठिन हो सकता है कि कोड आधार को प्राप्त करने वाले किसी व्यक्ति के लिए शीर्षक क्यों / कैसे बदल रहा है
ton.yeung

यह पता लगाना कठिन क्यों होगा? इस स्निप को एक निर्देश से ट्रिगर किया जाना चाहिए, अपने पृष्ठ-शीर्षक का कहना है = "{{'pageTitle' | Translate}}। यह निर्देश हर पृष्ठ के पहले तत्व में शामिल किया जाएगा। अच्छा और घोषणात्मक स्पष्ट।
मार्टिन

ओह, संपादन के साथ, मैं देख रहा हूं कि अब आपका क्या मतलब है। मेरा मतलब था कि एक लाइनर संभावित रूप से कहीं भी रखा जा सकता है, $ rootcope, निर्देश, आदि ...
ton.yeung

0

यदि आप ES6 का उपयोग कर रहे हैं, तो यह ठीक काम करता है :)।

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;

0

शायद आप इस निर्देश को आजमा सकते हैं।

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

यहाँ उदाहरण है:

एचटीएमएल:

<title dynamic-title>Title</title>

<a href="javascript:;" ui-sref="state1">State1 page</a>
<a href="javascript:;" ui-sref="state2">State2 page</a>

जावास्क्रिप्ट:

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

0

यूआई-राउटर 1.0.0+ संस्करणों के अपडेट के लिए, ( https://ui-router.github.io/guide/ng1/migrate-to-1_0 )

निम्न कोड का संदर्भ लें

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

अपने index.html में निम्नलिखित जोड़ें:

<title page-title ng-bind="page_title"></title>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.