AngularJS आंशिक दृश्य के आधार पर हेडर को गतिशील रूप से कैसे बदलें?


411

मैं AngularJS के आंशिक विचारों को शामिल करने के लिए एनजी-व्यू का उपयोग कर रहा हूं, और मैं शामिल दृश्य के आधार पर पेज शीर्षक और एच 1 हेडर टैग को अपडेट करना चाहता हूं। ये आंशिक दृश्य नियंत्रकों के दायरे से बाहर हैं, और इसलिए मैं यह पता नहीं लगा सकता कि उन्हें नियंत्रकों में डेटा सेट करने के लिए कैसे बाध्य किया जाए।

यदि यह ASP.NET MVC था, तो आप ऐसा करने के लिए @ViewBag का उपयोग कर सकते हैं, लेकिन मुझे AngularJS में समान नहीं पता है। मैंने साझा सेवाओं, घटनाओं आदि के बारे में खोज की है, लेकिन फिर भी यह काम नहीं कर पा रहा है। किसी भी तरह से मेरे उदाहरण को संशोधित करने के लिए यह काम करता है तो बहुत सराहना की जाएगी।

मेरा 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>

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

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

यह टिप्पणी शायद देर से ही सही लेकिन मैं जोड़ना चाहता हूं। cssfacts.com/simple-dynamic-meta-tags-in-angularjs यह सेट डायनामिक मेटा के लिए उपयोगी हो सकता है। आप बस अपने $ rootScope मेटा चर को बदल देंगे।
कामुरन सोनसेक

जवाबों:


342

आप <html>स्तर पर नियंत्रक को परिभाषित कर सकते हैं ।

 <html ng-app="app" ng-controller="titleCtrl">
   <head>
     <title>{{ Page.title() }}</title>
 ...

आप सेवा बनाएँ: Pageऔर नियंत्रकों से संशोधित करें।

myModule.factory('Page', function() {
   var title = 'default';
   return {
     title: function() { return title; },
     setTitle: function(newTitle) { title = newTitle }
   };
});

इंजेक्षन Page और नियंत्रकों से कॉल 'Page.setTitle ()'।

यहाँ ठोस उदाहरण है: http://plnkr.co/edit/0e7T6l


11
उहम् ... मुझे यकीन नहीं है कि $ स्कोप में एक सेवा को सीधे रखने पर एंगुलरजेएस वास्तुकला में अच्छा माना जाता है । शायद यह बेहतर हो सकता है कि $ गुंजाइश को एक नियंत्रक फ़ंक्शन में रखा जाए, और फिर इस फ़ंक्शन को सेवा को क्वेरी करने दें।
सुपरजोस

11
यह उदाहरण भयानक था। मेरे पास एक फॉलोअप है, प्रारंभिक लोड पर आप शीर्षक में {{Page.title ()}} पाठ (बहुत जल्दी) देख सकते हैं। मुझे नहीं लगता कि आप एनजी-क्लोक का उपयोग कर सकते हैं क्योंकि यह शरीर में नहीं है। इससे बचने के लिए कोई सुझाव?
आर्थर फ्रैंकेल

52
@ArthurFrankel बस एनजी-बिंद का उपयोग करें (जैसे एनजी-बिंद = "Page.title ()")
पायस उज़ामेरे

2
या हम शीर्षक टैग में नियंत्रक निर्दिष्ट कर सकते हैं, html हैडर पर वैश्विक नियंत्रक की कोई आवश्यकता नहीं है: <शीर्षक एनजी-नियंत्रक = "titleCtrl"> {{Page.title ()}} </ शीर्षक>
दिमित्री अल्गाज़िन

6
मैं व्यक्तिगत रूप से $rootScopeएक अतिरिक्त नियंत्रक बनाने के बजाय शीर्षक सेट करना पसंद करता हूं ।
DDA

634

यदि आपने राउटिंग का उपयोग कर रहे हैं तो मुझे अपना पृष्ठ शीर्षक सेट करने का एक अच्छा तरीका खोजा है:

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

var myApp = angular.module('myApp', ['ngResource'])

myApp.config(
    ['$routeProvider', function($routeProvider) {
        $routeProvider.when('/', {
            title: 'Home',
            templateUrl: '/Assets/Views/Home.html',
            controller: 'HomeController'
        });
        $routeProvider.when('/Product/:id', {
            title: 'Product',
            templateUrl: '/Assets/Views/Product.html',
            controller: 'ProductController'
        });
    }]);

myApp.run(['$rootScope', function($rootScope) {
    $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
        $rootScope.title = current.$$route.title;
    });
}]);

HTML:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="'myApp &mdash; ' + title">myApp</title>
...

संपादित करें : ng-bindकर्लियों के बजाय विशेषता का उपयोग {{}}करना ताकि वे लोड पर दिखाई न दें


11
ठीक है, लेकिन आपका उदाहरण $ मार्ग परिवर्तन शीर्षक को बदलने के लिए नहीं दिखाता है। $ गुंजाइश चर द्वारा मानकीकृत असफल, जो पृष्ठ सेवा का उपयोग करके @ tosh का उदाहरण देता है। तो आप सेट कर सकते हैं title = "Blog"लेकिन नहीं title = '{{"Blog post " + post.title}}'
एरिक ड्रेचेल

10
@ फेलिक्स आप जैसे शीर्षक का उपयोग कर सकते current.titleहैं
एल्डेलशेल

8
$ rootScope.title = current। $ path.title; बिना $ $ $
david.sansay

7
मैंने अपने कोणीय संस्करण को कई संस्करणों (1.0.5 से 1.2.7) में अपग्रेड किया और इसने मुझे अपने कोड में तोड़ दिया। मैं current.$routeपुराने कोड में उपयोग कर रहा था और यह काम कर रहा था। उन्नयन के साथ, मार्ग पर डबल $ की आवश्यकता है। current.$$route
टायलर फोर्सिथे

6
उत्तरदाता में जब देख सकते हैं '/Product/:id'। क्या :idइस विधि के साथ कोई मूल्य है? मैंने कोशिश की, title: function(params){return params.id;}लेकिन काम नहीं कर रहा है ... शायद का उपयोग कर resolve?
mickaelb91

190

ध्यान दें कि आप शीर्षक को सीधे जावास्क्रिप्ट के साथ सेट कर सकते हैं, अर्थात,

$window.document.title = someTitleYouCreated;

इसमें डेटा बाइंडिंग नहीं है, लेकिन टैग ng-appमें डालने <html>पर समस्या आती है। (उदाहरण के लिए, जेएसपी टेम्प्लेट का उपयोग करना जहां <head>बिल्कुल एक जगह परिभाषित किया गया है, फिर भी आपके पास एक से अधिक ऐप हैं।)


5
यह मेरे लिए इंटरनेट एक्सप्लोरर पर काम करने का एकमात्र तरीका था, अन्य तरीकों ने अन्य ब्राउज़रों पर काम किया हालांकि
Maarten

4
जैसा कि मैर्टन ने उल्लेख किया है कि यह एकमात्र ऐसा तरीका है जो आईई 7 और आईई 8 में काम करता है
लूट

33
आश्चर्यजनक है कि लोग कैसे पीछे नहीं हट सकते हैं और देख सकते हैं कि बिना
चीर फाड़

7
अविश्वसनीय। यह उन सभी शनीगनों की तुलना में कहीं अधिक सरल था जिनका अन्य उल्लेख कर रहे थे। धन्यवाद!
लियोनार्ड टेओ

8
सादे 'विंडो' का प्रयोग ठीक है - यह सीधे DOM पर काम कर रहा है। '$ विंडो' एक कोणीय चीज है, और आपको इसका उपयोग करने के लिए इसे इंजेक्ट करना होगा। किसी भी तरह से काम करेगा।
broc.seib 16

119

घोषणा ng-appपर htmlतत्व दोनों के लिए रूट गुंजाइश प्रदान करता है headऔर body

इसलिए अपने कंट्रोलर में $rootScopeइस पर हेडर प्रॉपर्टी इंजेक्ट करें और सेट करें:

function Test1Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 1"; }

function Test2Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 2"; }

और आपके पेज में:

<title ng-bind="header"></title>

8
मेरी राय पर सबसे अच्छा जवाब। एनजी-ऐप के स्तर पर नियंत्रक के रूप में स्वीकार किए गए उत्तर में वर्णित इस मामले में बेकार है।
निकोलस जेनेल

1
मैं प्यार करता हूँ कि यह समाधान कितना हल्का है, और यह $ $ गुण का उपयोग करने से बचता है
tedwards947

स्वीकृत उत्तर में अनावश्यक जटिलता और जोखिम शामिल हैं। यह संस्करण एक चर को सेट करने के रूप में सरल बनाता है।
special0ne

3
यदि आप $ rootScope का उपयोग करते हुए मृत हो गए हैं, तो मैं कम से कम इसे एक सेवा में निकाल दूंगा, ताकि आपके पास अपने नियंत्रक में $ rootScope न हो।
माइकल जे। कल्किंस

3
मैं इस समाधान का उपयोग करना चाहता हूं लेकिन मैं उत्सुक हूं कि इसका उपयोग करने के फायदे क्या हैं document.title = "App";
remarsh

43

मॉड्यूल कोणीयज-व्यूहेड केवल एक कस्टम निर्देश का उपयोग करके प्रति-दृश्य आधार पर शीर्षक सेट करने के लिए एक तंत्र को दर्शाता है।

इसे या तो मौजूदा व्यू एलिमेंट पर लागू किया जा सकता है, जिसकी सामग्री पहले से ही शीर्षक है:

<h2 view-title>About This Site</h2>

... या इसका उपयोग एक स्टैंडअलोन तत्व के रूप में किया जा सकता है, इस मामले में तत्व प्रदान किए गए दस्तावेज़ में अदृश्य होगा और केवल दृश्य शीर्षक सेट करने के लिए उपयोग किया जाएगा:

<view-title>About This Site</view-title>

इस निर्देश की सामग्री रूट स्कोप में उपलब्ध कराई गई है viewTitle, इसलिए इसे किसी अन्य वैरिएबल की तरह ही शीर्षक तत्व पर उपयोग किया जा सकता है:

<title ng-bind-template="{{viewTitle}} - My Site">My Site</title>

इसका उपयोग किसी अन्य स्थान पर भी किया जा सकता है जो रूट स्कोप को "देख" सकता है। उदाहरण के लिए:

<h1>{{viewTitle}}</h1>

यह समाधान शीर्षक को उसी तंत्र के माध्यम से सेट करने की अनुमति देता है जिसका उपयोग बाकी प्रस्तुति को नियंत्रित करने के लिए किया जाता है: AngularJS टेम्पलेट्स। यह इस तार्किक तर्क के साथ नियंत्रकों को बंद करने की आवश्यकता से बचा जाता है। नियंत्रक को किसी भी डेटा को उपलब्ध कराने की आवश्यकता होती है जिसे सूचित करने के लिए उपयोग किया जाएगा शीर्षक , लेकिन टेम्पलेट इसे कैसे प्रस्तुत करना है, इस पर अंतिम निर्धारण करता है, और डेटा को सामान्य करने के लिए बाँधने के लिए अभिव्यक्ति प्रक्षेप और फ़िल्टर का उपयोग कर सकता है।

(अस्वीकरण: मैं इस मॉड्यूल का लेखक हूं, लेकिन मैं इसे केवल इस उम्मीद में संदर्भित कर रहा हूं कि यह किसी और को इस समस्या को हल करने में मदद करेगा।)


4
विश्वास नहीं कर सकते हैं कि इस समाधान को और अधिक नहीं बनाया गया है। अधिकांश अन्य वास्तव में खराब डिजाइन विकल्प हैं।
मार्टिन वावरसच

सहमत, यह शीर्ष समाधान होना चाहिए। मुझे शीर्षक सेट करने के लिए पृष्ठ स्तर पर एक नियंत्रक घोषित करने की तुलना में यह बहुत अच्छा लगता है। FYI करें: इसे Angular v1.3.2 और कोणीय-मार्ग-खंड v1.3.3 के साथ उपयोग करना और यह एक आकर्षण की तरह काम कर रहा है।
नैट बारबेटिनी

मैं इस समाधान का समर्थन करता हूं;)
jkoreska

3
मैंने अपने ब्लॉग पर angularjs-viewhead और एक अन्य संबंधित विचार के बारे में थोड़ा और लिखा है: जाहिरा तौर
मार्टिन एटकिंस

यदि शीर्ष-स्तर पर और उप-स्तरीय दृश्य में समान दृश्य का पुन: उपयोग किया जा रहा है, तो कोई अभी भी एनजी-इफ के साथ व्यू-टाइटल का उपयोग कर सकता है, जैसे: <h4 एनजी-इफ = "$ State.includes ('some-state')" दृश्य-शीर्षक> {{...}} </ h4> <h4 ng-if = "के लिए विवरण! $ State.includes ('कुछ-राज्य')"> {{...}} के लिए विवरण </ h4 >
ऐरे

32

यहां एक अनुकूलित समाधान है जो मेरे लिए काम करता है जिसके लिए संसाधन विशिष्ट पृष्ठ शीर्षक सेट करने के लिए नियंत्रकों में $ rootScope के इंजेक्शन की आवश्यकता नहीं होती है।

मास्टर टेम्पलेट में:

<html data-ng-app="myApp">
    <head>
    <title data-ng-bind="page.title"></title>
    ...

रूटिंग कॉन्फ़िगरेशन में:

$routeProvider.when('/products', {
    title: 'Products',
    templateUrl: '/partials/products.list.html',
    controller: 'ProductsController'
});

$routeProvider.when('/products/:id', {
    templateUrl: '/partials/products.detail.html',
    controller: 'ProductController'
});

और रन ब्लॉक में:

myApp.run(['$rootScope', function($rootScope) {
    $rootScope.page = {
        setTitle: function(title) {
            this.title = title + ' | Site Name';
        }
    }

    $rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
        $rootScope.page.setTitle(current.$$route.title || 'Default Title');
    });
}]);

अंत में नियंत्रक में:

function ProductController($scope) {
    //Load product or use resolve in routing
    $scope.page.setTitle($scope.product.name);
}

1
ProductController ($ गुंजाइश.page.setTitle) में सेट किया गया शीर्षक $ rootScope द्वारा ओवरराइड किया जा रहा है। $ '(' $ pathChangeSuccess ') $ rootScope में एक डिफ़ॉल्ट शीर्षक सेट करना। $ (' $ मार्गChangeStart ') इस संबंध में अधिक सुरक्षित है।
क्रिस्टो औन

@ mr-hash: यहां मेरे द्वारा सुझाए गए छोटे समायोजन हैं, जो कई मार्गों के साथ मौजूदा कोणीय परियोजनाओं के लिए एकदम सही हैं, लेकिन बिना शीर्षक के। यह नियंत्रक के नाम से शीर्षक उत्पन्न करेगा, यदि कोई शीर्षक मार्ग पर परिभाषित नहीं किया गया है:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
mikhail-t

1
इस तरह से आउटपुट को सैनिटाइज करना याद रखें:this.title = title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ') + ' | Site Name';
हेनरिक स्टेनबेक

मुझे अपरिभाषित त्रुटि मिली, इसलिए मैंने अंतिम बिट को इसमें बदल दिया: $ rootScope.page.title = $$ रूट? करंट। $$ path.title + '| साइट का नाम ':' साइट का नाम ';
एंडी

15

jkoreska का समाधान एकदम सही है यदि आप हाथ से पहले खिताब जानते हैं, लेकिन आपको डेटा के आधार पर शीर्षक सेट करने की आवश्यकता हो सकती है जो आपको संसाधन आदि मिलते हैं।

मेरे समाधान के लिए एकल सेवा की आवश्यकता है। चूंकि rootScope सभी DOM तत्वों का आधार है, इसलिए हमें HTML तत्व पर किसी नियंत्रक का उल्लेख करने की आवश्यकता नहीं है

Page.js

app.service('Page', function($rootScope){
    return {
        setTitle: function(title){
            $rootScope.title = title;
        }
    }
});

index.jade

doctype html
html(ng-app='app')
head
    title(ng-bind='title')
// ...

सभी नियंत्रकों को शीर्षक बदलने की आवश्यकता है

app.controller('SomeController', function(Page){
    Page.setTitle("Some Title");
});

छोटी समस्या, जब आप किसी पृष्ठ को ताज़ा करते हैं, तो आपके टैब नाम में आप '{{शीर्षक}}' देखते हैं और पृष्ठ का प्रतिपादन होने के बाद, आप केवल 'कुछ शीर्षक' देखते हैं। कारखाने के साथ समाधान में वह व्यवहार नहीं होता है
दिमित्री अल्गाज़िन

5
इसके बजाय {{title}}उपयोगng-bind='title'
फैराडॉक्स

1
@Fadox के साथ सहमत ... का उपयोग करके ng-bindपूर्व-प्रक्षेपित सिंटैक्स को वास्तव में मूल्यांकन करने से पहले प्रदर्शित करने से रोकता है। +100
सेठ

11

एक साफ तरीका जो गतिशील रूप से शीर्षक या मेटा विवरण स्थापित करने की अनुमति देता है। उदाहरण के लिए, मैं यूआई-राउटर का उपयोग करता हूं लेकिन आप उसी तरह से एनकाउंटर का उपयोग कर सकते हैं।

var myApp = angular.module('myApp', ['ui.router'])

myApp.config(
    ['$stateProvider', function($stateProvider) {
        $stateProvider.state('product', {
            url: '/product/{id}',
            templateUrl: 'views/product.html',
            resolve: {
                meta: ['$rootScope', '$stateParams', function ($rootScope, $stateParams) {
                    var title = "Product " + $stateParams.id,
                        description = "Product " + $stateParams.id;
                    $rootScope.meta = {title: title, description: description};
                }]

                // Or using server side title and description
                meta: ['$rootScope', '$stateParams', '$http', function ($rootScope, $stateParams, $http) {
                    return $http({method: 'GET', url: 'api/product/ + $stateParams.id'})
                        .then (function (product) {
                            $rootScope.meta = {title: product.title, description: product.description};
                        });
                }]

            }
            controller: 'ProductController'
        });
    }]);

HTML:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="meta.title + ' | My App'">myApp</title>
...

8

वैकल्पिक रूप से, यदि आप यूआई-राउटर का उपयोग कर रहे हैं :

index.html

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="$state.current.data.title || 'App'">App</title>

रूटिंग

$stateProvider
  .state('home', {
      url: '/',
      templateUrl: 'views/home.html',
      data: {
        title: 'Welcome Home.'
      }
  }

2
मुझे यह काम करने के लिए नहीं मिल सकता है .. मुझे ui-routerअपने राज्य के आधार पर अपडेट करने वाला URL और सामग्री मिली है और मुझे कोई त्रुटि या चेतावनी नहीं मिली है, लेकिन मैं राज्य के किसी भी हिस्से को एक्सेस करने के लिए प्रतीत नहीं कर सकता $state.current.[...]ui-routerआपने इसे करने के लिए किस संस्करण का उपयोग किया?

मेरे "रनटाइम कॉन्फिगरेशन" के उत्तर को संपादित करने से मेरे द्वारा बताई गई समस्या का समाधान हो जाता है। :) मैं विचारों के लिए खुला हूँ अगर वहाँ यह करने के लिए एक बेहतर तरीका है।

यह मेरे लिए काम नहीं करता है और एपीआई डॉक्स में 'शीर्षक' नहीं मिला है - क्या यह अभी भी समर्थित है?
ग्राहमएफ

7

कस्टम घटना-आधारित समाधान

यहां एक और दृष्टिकोण है जिसका उल्लेख यहां (इस लेखन के रूप में) अन्य लोगों द्वारा नहीं किया गया है।

आप कस्टम इवेंट का उपयोग कर सकते हैं जैसे:

// your index.html template
<html ng-app="app">
<head>
<title ng-bind="pageTitle">My App</title>

// your main app controller that is declared on the <html> element
app.controller('AppController', function($scope) {
    $scope.$on('title-updated', function(newTitle) {
        $scope.pageTitle = newTitle;
    });
});

// some controller somewhere deep inside your app
mySubmodule.controller('SomeController', function($scope, dynamicService) {
    $scope.$emit('title-updated', dynamicService.title);
});

इस दृष्टिकोण का लाभ यह है कि अतिरिक्त सेवाओं को लिखने की आवश्यकता नहीं है और फिर प्रत्येक नियंत्रक में इंजेक्शन लगाया जाता है जिसे शीर्षक सेट करने की आवश्यकता होती है, और यह (ab) उपयोग नहीं करता है $rootScope। यह आपको एक गतिशील शीर्षक (जैसे कोड उदाहरण में) सेट करने की अनुमति देता है, जो कि राउटर के कॉन्फिग ऑब्जेक्ट पर कस्टम डेटा विशेषताओं का उपयोग करना संभव नहीं है (जहां तक ​​मुझे कम से कम पता है)।


5

परिदृश्यों के लिए जो आपके पास एक एनएपीएपी नहीं है जिसमें titleटैग शामिल है , बस नियंत्रकों के लिए एक सेवा इंजेक्ट करें जिसे विंडो शीर्षक सेट करने की आवश्यकता है।

var app = angular.module('MyApp', []);

app.controller('MyController', function($scope, SomeService, Title){
    var serviceData = SomeService.get();
    Title.set("Title of the page about " + serviceData.firstname);
});

app.factory('SomeService', function ($window) {
    return {
        get: function(){
            return { firstname : "Joe" };
        }
    };
});

app.factory('Title', function ($window) {
    return {
        set: function(val){
            $window.document.title = val;
        }
    };
});

काम करने का उदाहरण ... http://jsfiddle.net/8m379/1/


5

यदि आपके पास शीर्षक तत्व (जैसे asp.net वेब फ़ॉर्म) पर नियंत्रण नहीं है, तो यहां कुछ ऐसी चीज़ है जिसका आप उपयोग कर सकते हैं

var app = angular.module("myApp")
    .config(function ($routeProvider) {
                $routeProvider.when('/', {
                                            title: 'My Page Title',
                                            controller: 'MyController',
                                            templateUrl: 'view/myView.html'
                                        })
                            .otherwise({ redirectTo: '/' });
    })
    .run(function ($rootScope) {
        $rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) {
            document.title = currentRoute.title;
        });
    });

4

सरल और गंदा तरीका $rootScope:

<html ng-app="project">
<head>
<title ng-bind="title">Placeholder title</title>

अपने नियंत्रकों में, जब आपके पास शीर्षक बनाने के लिए आवश्यक डेटा होता है, तो:

$rootScope.title = 'Page X'

4

इन उत्तरों में से कोई भी पर्याप्त सहज नहीं लग रहा था, इसलिए मैंने ऐसा करने के लिए एक छोटा निर्देश बनाया। इस तरह से आप पृष्ठ में शीर्षक की घोषणा कर सकते हैं, जहां कोई सामान्य रूप से करेगा, और साथ ही इसे गतिशील होने की भी अनुमति देगा।

angular.module('myModule').directive('pageTitle', function() {
    return {
        restrict: 'EA',
        link: function($scope, $element) {
            var el = $element[0];
            el.hidden = true; // So the text not actually visible on the page

            var text = function() {
                return el.innerHTML;
            };
            var setTitle = function(title) {
                document.title = title;
            };
            $scope.$watch(text, setTitle);
        }
    };
});

आपको निश्चित रूप से अपने से मेल खाने के लिए मॉड्यूल का नाम बदलना होगा।

इसका उपयोग करने के लिए, बस इसे अपने विचार में फेंक दें, जितना आप एक नियमित <title>टैग के लिए करेंगे :

<page-title>{{titleText}}</page-title>

अगर आपको इसकी जरूरत नहीं है तो आप इसे केवल सादा पाठ शामिल कर सकते हैं:

<page-title>Subpage X</page-title>

वैकल्पिक रूप से, आप एक विशेषता का उपयोग कर सकते हैं, इसे और अधिक IE के अनुकूल बनाने के लिए:

<div page-title>Title: {{titleText}}</div>

आप पाठ्यक्रम के टैग में जो भी पाठ चाहते हैं, उसे आप कोणीय कोड सहित रख सकते हैं। इस उदाहरण में, यह $scope.titleTextकस्टम नियंत्रक शीर्षक टैग में वर्तमान में जो भी नियंत्रक के लिए दिखेगा ।

बस यह सुनिश्चित करें कि आपके पेज पर कई पेज-टाइटल टैग नहीं हैं, या वे एक-दूसरे को पसंद नहीं करेंगे।

Plunker यहाँ उदाहरण http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV । शीर्षक परिवर्तन देखने के लिए आपको ज़िप डाउनलोड करना होगा और इसे स्थानीय स्तर पर चलाना होगा।


मैं कुछ ऐसा ही लेकर आया हूं। अब तक का उपयोग करने के लिए सबसे सहज, और एक नियंत्रक डालने की आवश्यकता नहीं है html। अपने निर्देश में मैं एक वैकल्पिक pageTitlePrefixस्थिरांक भी इंजेक्ट करता हूं ।
zrr

4

कोणीय-यूआई-राउटर के लिए सरलीकृत समाधान:

HTML:

<html ng-app="myApp">
  <head>
     <title ng-bind="title"></title>
     .....
     .....  
  </head>
</html>

App.js> myApp.config ब्लॉक

$stateProvider
    .state("home", {
        title: "My app title this will be binded in html title",
        url: "/home",
        templateUrl: "/home.html",
        controller: "homeCtrl"
    })

App.js> myApp.run

myApp.run(['$rootScope','$state', function($rootScope,$state) {
   $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
    $rootScope.title = $state.current.title;
    console.log($state);
   });
}]);

3

यहां शीर्षक परिवर्तन करने का एक अलग तरीका है। शायद फैक्ट्री फ़ंक्शन के रूप में स्केलेबल नहीं है (जो असीमित पृष्ठों को समझ सकता है), लेकिन मेरे लिए यह समझना आसान था:

अपने index.html में मैंने इस तरह की शुरुआत की:

    <!DOCTYPE html>
      <html ng-app="app">
        <head>
          <title ng-bind-template="{{title}}">Generic Title That You'll Never See</title>

फिर मैंने "nav.html" नामक एक आंशिक बनाया:

<div ng-init="$root.title = 'Welcome'">
    <ul class="unstyled">
        <li><a href="#/login" ng-click="$root.title = 'Login'">Login</a></li>
        <li><a href="#/home" ng-click="$root.title = 'Home'">Home</a></li>
        <li><a href="#/admin" ng-click="$root.title = 'Admin'">Admin</a></li>
        <li><a href="#/critters" ng-click="$root.title = 'Crispy'">Critters</a></li>
    </ul>
</div>

फिर मैं "index.html" पर वापस चला गया और नेव-इन और मेरे भाग के लिए एनजी-व्यू का उपयोग करते हुए nav.html जोड़ा:

<body class="ng-cloak" ng-controller="MainCtrl">
    <div ng-include="'partials/nav.html'"></div>
    <div>
        <div ng-view></div>
    </div>

ध्यान दें कि एनजी-क्लोक? इसका इस जवाब से कोई लेना-देना नहीं है लेकिन यह पृष्ठ को तब तक छिपाता है जब तक कि यह लोड नहीं हो जाता है, एक अच्छा स्पर्श :) जानें कैसे यहां: Angularjs - ng-cloak / ng-show तत्व पलक

यहाँ मूल मॉड्यूल है। मैंने इसे "app.js" नामक फ़ाइल में डाला:

(function () {
    'use strict';
    var app = angular.module("app", ["ngResource"]);

    app.config(function ($routeProvider) {
        // configure routes
        $routeProvider.when("/", {
            templateUrl: "partials/home.html",
            controller:"MainCtrl"
        })
            .when("/home", {
            templateUrl: "partials/home.html",
            controller:"MainCtrl"
        })
            .when("/login", {
            templateUrl:"partials/login.html",
            controller:"LoginCtrl"
        })
            .when("/admin", {
            templateUrl:"partials/admin.html",
            controller:"AdminCtrl"
        })
            .when("/critters", {
            templateUrl:"partials/critters.html",
            controller:"CritterCtrl"
        })
            .when("/critters/:id", {
            templateUrl:"partials/critter-detail.html",
            controller:"CritterDetailCtrl"
        })
            .otherwise({redirectTo:"/home"});
    });

}());

यदि आप मॉड्यूल के अंत की ओर देखते हैं, तो आप देखेंगे कि मेरे पास एक critter- विवरण पृष्ठ है: id। यह एक आंशिक है जो क्रिस्पी क्रिटर्स पेज से उपयोग किया जाता है। [कॉर्नी, मुझे पता है - शायद यह एक ऐसी साइट है जो सभी प्रकार के चिकन नगेट्स का जश्न मनाती है;) वैसे भी, आप शीर्षक को अपडेट कर सकते हैं जब कोई उपयोगकर्ता किसी भी लिंक पर क्लिक करता है, तो मेरे मुख्य क्रिस्पी क्रिटर्स पेज में जो क्रेटर-डिटेल पेज पर जाता है। यह वह जगह है जहाँ $ root.title अपडेट जाएगा, जैसे आपने ऊपर दिए गए nav.html में देखा था:

<a href="#/critters/1" ng-click="$root.title = 'Critter 1'">Critter 1</a>
<a href="#/critters/2" ng-click="$root.title = 'Critter 2'">Critter 2</a>
<a href="#/critters/3" ng-click="$root.title = 'Critter 3'">Critter 3</a>

क्षमा करें इतनी हवा लेकिन मैं एक पोस्ट पसंद करता हूं जो इसे प्राप्त करने और चलाने के लिए पर्याप्त विवरण देता है। ध्यान दें कि AngularJS डॉक्स में उदाहरण पृष्ठ पुराना है और एनजी-बाइंड-टेम्प्लेट का 0.9 संस्करण दिखाता है। आप देख सकते हैं कि यह उतना अलग नहीं है।

बाद में: आप यह जानते हैं लेकिन यह किसी और के लिए यहाँ है; index.html में सबसे नीचे, किसी को मॉड्यूल के साथ app.js शामिल करना चाहिए:

        <!-- APP -->
        <script type="text/javascript" src="js/app.js"></script>
    </body>
</html>

2
मेरी राय, यह प्रयोग न करें। आप विचारों (प्रस्तुति) में डेटा (सूचना) का मिश्रण कर रहे हैं। बाद में यह आपके HTML लिंक पर बिखरे शीर्षक स्रोतों को खोजना बहुत मुश्किल होगा जो दृश्य में विभिन्न स्थानों पर मौजूद हो सकते हैं ..
amit bakle

क्योंकि शीर्षक केवल वास्तव में लिंक पर क्लिक करने पर अद्यतन हो जाता है , यह सही ढंग से शीर्षक सेट नहीं करता है जब उपयोगकर्ता किसी पृष्ठ पर पहली बार लैंड करता है, या जब उपयोगकर्ता ताज़ा करता है।
मार्क अमेरी

3

जब मुझे इसे हल करना था, तो मैं ng-appपेज के htmlटैग पर जगह नहीं दे सकता था , इसलिए मैंने इसे एक सेवा के साथ हल किया:

angular.module('myapp.common').factory('pageInfo', function ($document) {

    // Public API
    return {
        // Set page <title> tag. Both parameters are optional.
        setTitle: function (title, hideTextLogo) {
            var defaultTitle = "My App - and my app's cool tagline";
            var newTitle = (title ? title : defaultTitle) + (hideTextLogo ? '' : ' - My App')
            $document[0].title = newTitle;
        }
    };

});

2

कस्टम इवेंट आधारित समाधान माइकल ब्रोमली से प्रेरित है

मैं इसे $ गुंजाइश के साथ काम करने में सक्षम नहीं था, इसलिए मैंने रूटस्स्कोप के साथ कोशिश की, शायद थोड़ा अधिक गंदा ... (खासकर यदि आप उस पृष्ठ पर ताज़ा करते हैं जो घटना को पंजीकृत नहीं करते हैं)

लेकिन मुझे वास्तव में यह विचार पसंद है कि कैसे चीजें शिथिल होती हैं।

मैं angularjs 1.6.9 का उपयोग कर रहा हूं

index.run.js

angular
.module('myApp')
.run(runBlock);

function runBlock($rootScope, ...)
{
  $rootScope.$on('title-updated', function(event, newTitle) {
    $rootScope.pageTitle = 'MyApp | ' + newTitle;
  });
}

anyController.controller.js

angular
.module('myApp')
.controller('MainController', MainController);

function MainController($rootScope, ...)
{
  //simple way :
  $rootScope.$emit('title-updated', 'my new title');

  // with data from rest call
  TroncQueteurResource.get({id:tronc_queteur_id}).$promise.then(function(tronc_queteur){
  vm.current.tronc_queteur = tronc_queteur;

  $rootScope.$emit('title-updated', moment().format('YYYY-MM-DD') + ' - Tronc '+vm.current.tronc_queteur.id+' - ' +
                                             vm.current.tronc_queteur.point_quete.name + ' - '+
                                             vm.current.tronc_queteur.queteur.first_name +' '+vm.current.tronc_queteur.queteur.last_name
  );
 });

 ....}

index.html

<!doctype html>
<html ng-app="myApp">
  <head>
    <meta charset="utf-8">
    <title ng-bind="pageTitle">My App</title>

यह मेरे लिए काम कर रहा है :)



1

जबकि अन्य में बेहतर तरीके हो सकते हैं, मैं अपने नियंत्रकों में $ rootScope का उपयोग करने में सक्षम था, क्योंकि मेरे प्रत्येक दृश्य / टेम्पलेट्स में एक अलग नियंत्रक है। आपको प्रत्येक कंट्रोलर में $ rootScope इंजेक्ट करने की आवश्यकता होगी। हालांकि यह आदर्श नहीं हो सकता है, यह मेरे लिए कार्य कर रहा है, इसलिए मैंने सोचा कि मुझे इसे पास करना चाहिए। यदि आप पृष्ठ का निरीक्षण करते हैं, तो यह एनजी-बाइंडिंग को शीर्षक टैग में जोड़ता है।

उदाहरण नियंत्रक:

myapp.controller('loginPage', ['$scope', '$rootScope', function ($scope, $rootScope) {

// Dynamic Page Title and Description
$rootScope.pageTitle = 'Login to Vote';
$rootScope.pageDescription = 'This page requires you to login';
}]);

उदाहरण Index.html शीर्षक:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="description" content="{{pageDescription}}">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.ico">
<base href="/">
<title>{{pageTitle}}</title>

आप पेजटेटल और पेजडेसक्रिप्शन को डायनेमिक वैल्यू पर भी सेट कर सकते हैं, जैसे कि REST कॉल से डेटा लौटना:

    $scope.article = restCallSingleArticle.get({ articleID: $routeParams.articleID }, function() {
    // Dynamic Page Title and Description
    $rootScope.pageTitle = $scope.article.articletitle;
    $rootScope.pageDescription = $scope.article.articledescription;
});

फिर, दूसरों के पास इस बारे में बेहतर विचार हो सकते हैं कि यह कैसे किया जाए, लेकिन जब से मैं पूर्व-प्रतिपादन का उपयोग कर रहा हूं, मेरी जरूरतों को पूरा किया जा रहा है।


0

उसके समाधान के लिए tosh shimayama का धन्यवाद ।
मैंने सोचा था कि किसी सेवा को सीधे अंदर रखना इतना साफ नहीं था $scope, इसलिए यहाँ पर मेरी थोड़ी भिन्नता है: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

नियंत्रक (जो मूल उत्तर में मुझे थोड़ा बहुत गूंगा लग रहा था) एक ActionBar ऑब्जेक्ट बनाता है, और यह एक $ स्कोप में भर जाता है।
ऑब्जेक्ट वास्तव में सेवा को क्वेरी करने के लिए जिम्मेदार है। यह टेम्प्लेट URL को सेट करने के लिए $ स्कोप कॉल से भी छुपाता है, जो इसके बजाय अन्य नियंत्रकों के लिए URL सेट करने के लिए उपलब्ध है।


0

श्री हैश के पास अब तक का सबसे अच्छा जवाब था, लेकिन नीचे दिए गए समाधान इसे निम्नलिखित लाभों को जोड़कर आदर्श (मेरे लिए) बनाता है:

  • कोई घड़ियों को जोड़ता है, जो चीजों को धीमा कर सकता है
  • वास्तव में नियंत्रक में मैंने जो किया है, उसे स्वचालित करता है, फिर भी
  • अगर मुझे अभी भी यह चाहिए तो फिर भी मुझे कंट्रोलर से एक्सेस मिलेगा।
  • कोई अतिरिक्त इंजेक्शन नहीं

राउटर में:

  .when '/proposals',
    title: 'Proposals',
    templateUrl: 'proposals/index.html'
    controller: 'ProposalListCtrl'
    resolve:
      pageTitle: [ '$rootScope', '$route', ($rootScope, $route) ->
        $rootScope.page.setTitle($route.current.params.filter + ' ' + $route.current.title)
      ]

रन ब्लॉक में:

.run(['$rootScope', ($rootScope) ->
  $rootScope.page =
    prefix: ''
    body: ' | ' + 'Online Group Consensus Tool'
    brand: ' | ' + 'Spokenvote'
    setTitle: (prefix, body) ->
      @prefix = if prefix then ' ' + prefix.charAt(0).toUpperCase() + prefix.substring(1) else @prifix
      @body = if body then ' | ' + body.charAt(0).toUpperCase() + body.substring(1) else @body
      @title = @prefix + @body + @brand
])

-4

मैंने पाया है कि बेहतर और गतिशील समाधान चर परिवर्तन का पता लगाने और फिर शीर्षक को अपडेट करने के लिए $ घड़ी का उपयोग करना है।

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