Bagaimana cara mengubah tajuk secara dinamis berdasarkan tampilan parsial AngularJS?

411

Saya menggunakan ng-view untuk menyertakan tampilan parsial AngularJS, dan saya ingin memperbarui judul halaman dan tag header h1 berdasarkan pada tampilan yang disertakan. Ini berada di luar jangkauan pengendali tampilan parsial, jadi saya tidak tahu cara mengikatnya ke kumpulan data di pengontrol.

Jika itu adalah ASP.NET MVC Anda bisa menggunakan @ViewBag untuk melakukan ini, tapi saya tidak tahu padanannya di AngularJS. Saya telah mencari tentang layanan bersama, acara dll tetapi masih tidak bisa berfungsi. Cara apa pun untuk mengubah contoh saya sehingga berfungsi akan sangat dihargai.

HTML saya:

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

JavaScript saya:

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"; }
Mikel
sumber
Komentar ini mungkin terlambat tetapi saya ingin menambahkan. cssfacts.com/simple-dynamic-meta-tags-in-angularjs Ini dapat berguna untuk mengatur meta dinamis. Anda hanya akan mengubah variabel meta $ rootScope Anda.
Kamuran Sönecek

Jawaban:

342

Anda bisa mendefinisikan pengontrol di <html>level.

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

Anda membuat layanan: Pagedan memodifikasi dari pengontrol.

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

Suntikkan Pagedan Panggil 'Page.setTitle ()' dari pengontrol.

Berikut adalah contoh konkret: http://plnkr.co/edit/0e7T6l

Omong kosong
sumber
11
uhmm ... Saya tidak yakin apakah menempatkan layanan langsung ke $ scope dianggap bagus dalam arsitektur AngularJS. Mungkin lebih baik memasukkan $ scope fungsi Controller, dan kemudian membiarkan fungsi ini meminta layanan.
superjos
11
Contoh ini luar biasa. Saya memiliki satu tindak lanjut, pada pemuatan awal Anda dapat melihat teks {{Page.title ()}} dalam judul (sangat cepat). Saya tidak berpikir Anda bisa menggunakan ng-jubah karena tidak ada di tubuh. Ada saran untuk menghindari ini?
Arthur Frankel
52
@ArthurFrankel Cukup gunakan ng-bind (mis. Ng-bind = "Page.title ()")
Pius Uzamere
2
atau kita dapat menentukan pengontrol di tag judul, tidak perlu pengontrol global di header html: <title ng-controller = "titleCtrl"> {{Page.title ()}} </title>
Dmitri Algazin
6
Saya pribadi lebih suka mengatur judul $rootScopedaripada membuat controller tambahan.
DDA
634

Saya baru saja menemukan cara yang bagus untuk mengatur judul halaman Anda jika Anda menggunakan perutean:

JavaScript:

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

Sunting : menggunakan ng-bindatribut alih-alih ikal {{}}agar tidak ditampilkan saat dimuat

jkoreska
sumber
11
benar, tetapi contoh Anda tidak menunjukkan bagaimana mengubah judul pada $ routeChangeSuccess diparameterisasi oleh variabel $ scope, yang contoh @ tosh menggunakan layanan Halaman tidak. Jadi Anda bisa mengatur title = "Blog"tetapi tidak title = '{{"Blog post " + post.title}}'.
Eric Drechsel
10
@ Feliks Anda dapat mengakses judul seperti current.titlejuga
Eldelshell
8
$ rootScope.title = saat ini. $ route.title; tanpa doble $$
david.sansay
7
Saya baru saja memutakhirkan versi Angular saya beberapa versi (1.0.5 ke 1.2.7) dan ini mematahkan saya dalam kode saya. Saya menggunakan current.$routekode lama dan itu berfungsi. Dengan peningkatan, $ ganda pada rute diperlukan. current.$$route
Tyler Forsythe
6
Di penjawab kapan bisa melihat '/Product/:id'. Apakah ada cara untuk memiliki :idnilai dengan metode ini? Saya mencoba title: function(params){return params.id;}tetapi tidak berhasil ... Mungkin menggunakan resolve?
mickaelb91
190

Perhatikan bahwa Anda juga dapat mengatur judul secara langsung dengan javascript, yaitu,

$window.document.title = someTitleYouCreated;

Ini tidak memiliki data yang mengikat, tapi itu sudah cukup saat meletakkan ng-appdi <html>tag bermasalah. (Misalnya, menggunakan templat JSP di mana <head>didefinisikan tepat di satu tempat, namun Anda memiliki lebih dari satu aplikasi.)

broc.seib
sumber
5
Ini adalah satu-satunya cara untuk membuatnya bekerja di Internet Explorer untuk saya, metode lain bekerja pada browser lain
Maarten
4
Seperti yang disebutkan oleh Maarten, ini adalah satu-satunya pendekatan yang bekerja pada ie7 dan ie8
rob
33
Luar biasa bagaimana orang tidak bisa mundur dan melihat betapa mudahnya hal ini dapat dilakukan tanpa ruang lingkup dan pabrik
redben
7
Luar biasa. Ini jauh lebih sederhana daripada semua shenanigans lain yang disebutkan. Terima kasih!
Leonard Teo
8
Menggunakan 'jendela' polos tidak masalah - itu langsung bekerja pada DOM. '$ window' adalah hal yang bersudut, dan Anda harus menyuntikkannya untuk menggunakannya. Apa pun caranya akan berhasil.
broc.seib
119

Menyatakan ng-apppada htmlelemen menyediakan ruang lingkup akar untuk kedua headdan body.

Karenanya di controller Anda menyuntikkan $rootScopedan mengatur properti header pada ini:

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

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

dan di halaman Anda:

<title ng-bind="header"></title>
Andy Hitchman
sumber
8
jawaban terbaik menurut pendapat saya. Untuk memiliki pengontrol pada tingkat aplikasi-seperti yang dijelaskan dalam jawaban yang diterima tidak berguna dalam kasus ini.
Nicolas Janel
1
Saya suka betapa ringannya solusi ini, dan ia tidak menggunakan properti $$
tedwards947
Jawaban yang diterima menambah komplikasi dan risiko yang tidak perlu. Versi ini membuatnya sesederhana mengatur variabel.
spesial0ne
3
Jika Anda mati untuk menggunakan $ rootScope saya setidaknya mengekstrak ini ke layanan sehingga Anda tidak memiliki $ rootScope di controller Anda.
Michael J. Calkins
3
Saya ingin menggunakan solusi ini tetapi saya ingin tahu apa kelebihan dari menggunakannya document.title = "App";
Remarsh
43

Modul angularjs-viewhead menunjukkan mekanisme untuk menetapkan judul berdasarkan per-view hanya menggunakan arahan khusus.

Ini dapat diterapkan ke elemen tampilan yang sudah ada yang kontennya sudah menjadi judul tampilan:

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

... atau dapat digunakan sebagai elemen mandiri, dalam hal ini elemen tersebut tidak akan terlihat dalam dokumen yang diberikan dan hanya akan digunakan untuk mengatur judul tampilan:

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

Isi dari arahan ini tersedia dalam ruang lingkup root sebagai viewTitle, sehingga dapat digunakan pada elemen judul seperti variabel lain:

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

Itu juga dapat digunakan di tempat lain yang dapat "melihat" lingkup root. Sebagai contoh:

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

Solusi ini memungkinkan judul diatur melalui mekanisme yang sama yang digunakan untuk mengontrol sisa presentasi: Templat AngularJS. Ini menghindari perlunya mengacaukan pengontrol dengan logika presentasi ini. Pengontrol perlu menyediakan data apa pun yang akan digunakan untuk menginformasikan judul, tetapi templat membuat penentuan akhir tentang cara menyajikannya, dan dapat menggunakan interpolasi ekspresi dan filter untuk mengikat ke ruang lingkup data seperti biasa.

(Penafian: Saya adalah penulis modul ini, tapi saya merujuknya di sini hanya dengan harapan akan membantu orang lain untuk menyelesaikan masalah ini.)

Martin Atkins
sumber
4
Tidak percaya solusi ini belum ter-upgrade. Sebagian besar yang lain adalah pilihan desain yang sangat buruk.
Martin Wawrusch
Setuju, ini harus menjadi solusi utama. Saya suka ini jauh lebih baik daripada mendeklarasikan pengontrol di tingkat halaman untuk mengatur judul. FYI: menggunakan ini dengan Angular v1.3.2 dan angular-route-segment v1.3.3 dan bekerja seperti pesona.
Nate Barbettini
Saya mendukung solusi ini;)
jkoreska
3
Saya menulis sedikit tentang angularjs-viewhead dan ide terkait lain di sini di blog saya: apparently.me.uk/angularjs-view-specific-sidebars
Martin Atkins
Jika menggunakan kembali tampilan yang sama di tampilan tingkat atas dan sub-level, Anda masih dapat menggunakan judul tampilan dengan ng-if, mis .: <h4 ng-if = "$ state.includes ('some-state')" view-title> Detail untuk {{...}} </h4> <h4 ng-if = "! $ state.includes ('some-state')"> Detail untuk {{...}} </ h4 >
anre
32

Berikut ini adalah solusi yang diadaptasi yang berfungsi untuk saya yang tidak memerlukan injeksi $ rootScope ke dalam pengontrol untuk mengatur judul halaman sumber daya tertentu.

Di templat induk:

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

Dalam konfigurasi routing:

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

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

Dan di blok run:

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

Akhirnya di controller:

function ProductController($scope) {
    //Load product or use resolve in routing
    $scope.page.setTitle($scope.product.name);
}
Tuan Hash
sumber
1
Judul yang ditetapkan di ProductController ($ scope.page.setTitle) sedang diganti oleh $ rootScope. $ On ('$ routeChangeSuccess'. Mengatur judul default di $ rootScope. $ On ('$ routeChangeStart' lebih aman dalam hal ini.
Kristo Aun
@ mr-hash: di sini adalah penyesuaian kecil saya sarankan, sempurna untuk proyek sudut yang ada dengan banyak rute, tetapi tanpa judul. Ini akan menghasilkan judul dari nama pengontrol, jika tidak ada judul yang ditentukan pada rute:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
mikhail-t
1
ingat untuk membersihkan output seperti ini:this.title = title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ') + ' | Site Name';
Henrik Stenbæk
Saya mendapat kesalahan yang tidak terdefinisi jadi saya mengubah bit terakhir menjadi: $ rootScope.page.title = saat ini. $$ rute? saat ini. $$ route.title + '| Nama Situs ':' Nama Situs ';
Andy
15

solusi jkoreska sangat cocok jika Anda tahu judul sebelumnya, tetapi Anda mungkin perlu mengatur judul berdasarkan data yang Anda dapatkan dari sumber daya dll.

Solusi saya memerlukan satu layanan. Karena rootScope adalah basis dari semua elemen DOM, kita tidak perlu meletakkan pengontrol pada elemen html seperti seseorang yang disebutkan

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')
// ...

Semua pengontrol yang perlu mengubah judul

app.controller('SomeController', function(Page){
    Page.setTitle("Some Title");
});
Deminetix
sumber
masalah kecil, ketika Anda me-refresh halaman, dalam nama tab Anda, Anda melihat '{{title}}' dan setelah halaman dirender, Anda melihat 'Some Title' saja. solusi dengan pabrik tidak memiliki perilaku itu
Dmitri Algazin
5
alih-alih {{title}}gunakanng-bind='title'
Faradox
1
Setuju dengan @Faradox ... menggunakan ng-bindmencegah sintaks pra-interpolasi dari menampilkan sebelum judul benar-benar mengevaluasi. +100
Seth
11

Cara bersih yang memungkinkan pengaturan judul atau deskripsi meta secara dinamis. Dalam contoh saya menggunakan ui-router tetapi Anda dapat menggunakan ngRoute dengan cara yang sama.

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>
...
Alex Soroka
sumber
8

Atau, jika Anda menggunakan ui-router :

index.html

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

Rute

$stateProvider
  .state('home', {
      url: '/',
      templateUrl: 'views/home.html',
      data: {
        title: 'Welcome Home.'
      }
  }
Nathan Kot
sumber
2
Saya tidak dapat mengaktifkan ini .. Saya harus ui-routermemperbarui URL dan konten berdasarkan kondisi saya dan saya tidak mendapatkan kesalahan atau peringatan, tetapi saya tidak dapat mengakses bagian mana pun dari objek konfigurasi negara $state.current.[...]. Versi apa yang ui-routerAnda gunakan untuk melakukan ini?
Suntingan "Runtime Config" saya pada jawaban menyelesaikan masalah yang saya sebutkan di komentar saya di atas. :) Saya terbuka untuk ide-ide jika ada cara yang lebih baik untuk melakukan ini.
ini tidak berfungsi untuk saya dan 'judul' tidak ditemukan di API API - apakah ini masih didukung?
GraehamF
7

Solusi berbasis acara khusus

Berikut adalah pendekatan lain yang belum disebutkan oleh yang lain di sini (pada tulisan ini).

Anda dapat menggunakan acara khusus seperti:

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

Pendekatan ini memiliki keuntungan karena tidak memerlukan layanan tambahan untuk ditulis dan kemudian disuntikkan ke setiap pengontrol yang perlu mengatur judul, dan juga tidak (ab) menggunakan $rootScope. Ini juga memungkinkan Anda untuk mengatur judul dinamis (seperti dalam contoh kode), yang tidak mungkin menggunakan atribut data khusus pada objek konfigurasi router (sejauh yang saya tahu setidaknya).

Michael Bromley
sumber
5

Untuk skenario yang tidak memiliki ngApp yang berisi titletag, cukup masukkan layanan ke pengontrol yang perlu mengatur judul jendela.

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

Contoh kerja ... http://jsfiddle.net/8m379/1/

JeremyWeir
sumber
5

Jika Anda tidak memiliki kendali atas elemen judul (seperti formulir web asp.net) di sini adalah beberapa hal yang dapat Anda gunakan

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;
        });
    });
Ashish
sumber
4

Cara sederhana dan kotor menggunakan $rootScope:

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

Di pengontrol Anda, ketika Anda memiliki data yang diperlukan untuk membuat judul, lakukan:

$rootScope.title = 'Page X'
pengguna1338062
sumber
4

Tidak satu pun dari jawaban ini yang tampaknya cukup intuitif, jadi saya membuat arahan kecil untuk melakukan ini. Cara ini memungkinkan Anda untuk mendeklarasikan judul di halaman, di mana orang biasanya melakukannya, dan memungkinkannya menjadi dinamis juga.

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

Tentu saja Anda harus mengubah nama modul agar sesuai dengan Anda.

Untuk menggunakannya, cukup lempar ini ke tampilan Anda, seperti yang Anda lakukan pada <title>tag biasa :

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

Anda juga bisa memasukkan teks biasa jika Anda tidak membutuhkannya secara dinamis:

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

Atau, Anda bisa menggunakan atribut, agar lebih ramah IE:

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

Anda dapat memasukkan teks apa pun yang Anda inginkan dalam tag, termasuk kode Angular. Dalam contoh ini, ini akan dicari$scope.titleText di mana controller tag judul kustom saat ini masuk

Pastikan Anda tidak memiliki beberapa tag judul halaman pada halaman Anda, atau mereka akan saling mengalahkan.

Contoh plunker di sini http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV . Anda harus mengunduh zip dan menjalankannya secara lokal untuk melihat perubahan judul.

MikeyB
sumber
Saya datang dengan sesuatu yang serupa. Sejauh ini yang paling intuitif untuk digunakan, dan tidak memerlukan pengontrol html. Dalam arahan saya, saya juga menyuntikkan pageTitlePrefixkonstanta opsional .
z0r
4

Solusi sederhana untuk angular-ui-router:

HTML:

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

App.js> blok 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);
   });
}]);
the_mishra
sumber
3

Berikut cara berbeda untuk melakukan perubahan judul. Mungkin tidak scalable seperti fungsi pabrik (yang bisa menangani halaman tanpa batas) tetapi lebih mudah bagi saya untuk mengerti:

Di index.html saya, saya mulai seperti ini:

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

Lalu saya membuat sebagian yang disebut "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>

Kemudian saya kembali ke "index.html" dan menambahkan nav.html menggunakan ng-include dan ng-view untuk parsial saya:

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

Perhatikan bahwa ng-jubah? Tidak ada hubungannya dengan jawaban ini tetapi menyembunyikan halaman sampai selesai memuat, sentuhan yang bagus :) Pelajari caranya di sini: Angularjs - ng-cloak / ng-show elements blink

Inilah modul dasar. Saya memasukkannya ke dalam file bernama "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"});
    });

}());

Jika Anda melihat ke bagian akhir modul, Anda akan melihat bahwa saya memiliki halaman detail makhluk berdasarkan: id. Ini sebagian yang digunakan dari halaman Crispy Critters. [Corny, saya tahu - mungkin ini adalah situs yang merayakan semua jenis nugget ayam;) Bagaimanapun, Anda dapat memperbarui judul ketika pengguna mengklik tautan apa pun, jadi di halaman Crispy Critters utama saya yang mengarah ke halaman detail makhluk, di situlah pembaruan $ root.title akan muncul, seperti yang Anda lihat di nav.html di atas:

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

Maaf sangat berangin, tetapi saya lebih suka posting yang memberikan detail yang cukup untuk menjalankannya. Perhatikan bahwa halaman contoh dalam dokumen AngularJS kedaluwarsa dan menunjukkan versi ng-bind-template versi 0.9. Anda dapat melihat bahwa itu tidak jauh berbeda.

Setelah Pikir: Anda tahu ini tetapi ada di sini untuk orang lain; di bagian bawah index.html, seseorang harus menyertakan app.js dengan modul:

        <!-- APP -->
        <script type="text/javascript" src="js/app.js"></script>
    </body>
</html>
noogrub
sumber
2
Pendapat saya, jangan gunakan ini. Anda mencampur data (informasi) dalam tampilan (presentasi). Nantinya akan sangat sulit untuk menemukan sumber judul yang tersebar di seluruh tautan HTML Anda yang mungkin ada di berbagai tempat dalam tampilan ..
amit bakle
Karena judul hanya akan diperbarui setelah mengklik tautan , ini tidak mengatur judul dengan benar ketika pengguna pertama kali mendarat di halaman, atau ketika pengguna menyegarkan.
Mark Amery
3

Ketika saya harus menyelesaikan ini, saya tidak dapat menempatkan tag ng-apppada halaman html, jadi saya menyelesaikannya dengan sebuah layanan:

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

});
Tom Söderlund
sumber
2

Solusi Custom Event Based terinspirasi dari Michael Bromley

Saya tidak dapat membuatnya berfungsi dengan $ scope, jadi saya mencoba dengan rootScope, mungkin sedikit lebih kotor ... (terutama jika Anda melakukan penyegaran pada halaman yang tidak mendaftarkan acara)

Tetapi saya benar-benar menyukai gagasan tentang bagaimana berbagai hal digabungkan secara longgar.

Saya menggunakan 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>

Ini bekerja untuk saya :)


Thomas
sumber
1

Sementara yang lain mungkin memiliki metode yang lebih baik, saya dapat menggunakan $ rootScope di controller saya, karena masing-masing pandangan saya / templat memiliki pengontrol yang berbeda. Anda harus menyuntikkan $ rootScope di setiap pengontrol. Walaupun ini mungkin tidak ideal, ini berfungsi untuk saya, jadi saya pikir saya harus meneruskannya. Jika Anda memeriksa halaman, itu menambah pengikatan ke tag judul.

Pengontrol Contoh:

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

Contoh Index.html tajuk:

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

Anda juga dapat mengatur pageTitle dan pageDescription ke nilai dinamis, seperti mengembalikan data dari panggilan REST:

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

Sekali lagi, orang lain mungkin memiliki ide yang lebih baik tentang cara mendekati ini, tetapi karena saya menggunakan pra-rendering, kebutuhan saya terpenuhi.

Kode
sumber
0

Terima kasih tosh shimayama untuk solusinya.
Saya pikir itu tidak begitu bersih untuk menempatkan layanan langsung ke $scope, jadi inilah sedikit variasi saya tentang itu: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

Kontroler (yang dalam jawaban aslinya menurut saya sedikit terlalu bodoh) menciptakan objek ActionBar, dan yang ini dimasukkan ke dalam $ scope.
Objek bertanggung jawab untuk benar-benar menanyakan layanan. Itu juga menyembunyikan dari $ scope panggilan untuk mengatur URL templat, yang sebaliknya tersedia untuk pengontrol lain untuk mengatur URL.

superjos
sumber
0

Mr Hash memiliki jawaban terbaik sejauh ini, tetapi solusi di bawah ini membuatnya ideal (untuk saya) dengan menambahkan manfaat berikut:

  • Menambahkan tidak ada jam tangan, yang dapat memperlambat segalanya
  • Sebenarnya mengotomatiskan apa yang mungkin telah saya lakukan di controller, belum
  • Masih memberi saya akses dari controller jika saya masih menginginkannya.
  • Tidak ada suntikan ekstra

Di router:

  .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)
      ]

Di blok run:

.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
])
Kim Miller
sumber
-4

Solusi yang lebih baik dan dinamis yang saya temukan adalah menggunakan $ watch untuk melacak perubahan variabel dan kemudian memperbarui judulnya.

geolyth
sumber