AngularJS kısmi görünümüne göre başlığı dinamik olarak nasıl değiştirebilirim?


411

AngularJS kısmi görünümleri dahil etmek için ng-view kullanıyorum ve dahil edilen görünüme göre sayfa başlığı ve h1 başlık etiketlerini güncellemek istiyorum. Bunlar kısmi görünüm denetleyicilerinin kapsamı dışındadır ve bu yüzden onları denetleyicilerdeki veri kümesine nasıl bağlayacağımı anlayamıyorum.

ASP.NET MVC ise bunu yapmak için @ViewBag kullanabilirsiniz, ancak AngularJS eşdeğerini bilmiyorum. Paylaşılan hizmetler, etkinlikler vb. Hakkında arama yaptım, ancak yine de çalışamıyor. Örneğimi çalıştıracak şekilde değiştirmenin herhangi bir yolu çok takdir edilecektir.

HTML kodum:

<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'im:

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

Bu yorum belki geç olabilir ama eklemek istiyorum. cssfacts.com/simple-dynamic-meta-tags-in-angularjs Bu, dinamik metas ayarlamak için yararlı olabilir. Sadece $ rootScope meta değişkeninizi değiştireceksiniz.
Kamuran Sönecek

Yanıtlar:


342

Denetleyiciyi <html>seviyede tanımlayabilirsiniz .

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

Service: oluşturursunuz Pageve denetleyicilerden değişiklik yaparsınız .

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

inject PageDenetleyiciden 'Page.setTitle ()' ve çağırın.

Somut örnek: http://plnkr.co/edit/0e7T6l


11
uhmm ... AngularJS mimarisinde doğrudan $ kapsamına bir hizmet yerleştirmenin güzel kabul edilip edilmediğinden emin değilim . Belki $ kapsamına bir Controller işlevi koymak ve daha sonra bu işlevin hizmeti sorgulamasına izin vermek daha iyi olabilir.
superjos

11
Bu örnek müthişti. Bir takip var, ancak ilk yükte {{Page.title ()}} metin başlık (çok hızlı bir şekilde) görebilirsiniz. Vücutta olmadığından ng-cloak kullanabileceğinizi sanmıyorum. Bundan kaçınmak için herhangi bir öneriniz var mı?
Arthur Frankel

52
@ArthurFrankel Sadece ng-bind kullanın (örneğin ng-bind = "Page.title ()")
Pius Uzamere

2
veya başlık etiketinde denetleyici belirtebiliriz, html üstbilgisinde genel denetleyiciye gerek yoktur: <title ng-controller = "titleCtrl"> {{Page.title ()}} </title>
Dmitri Algazin

6
Şahsen $rootScopeek bir denetleyici oluşturmak yerine başlığı ayarlamayı tercih ediyorum .
DDA

634

Yönlendirme kullanıyorsanız sayfa başlığınızı ayarlamanın güzel bir yolunu keşfettim:

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

Düzenleme : yükte görünmemesi için ng-bindkıvrımlar yerine özniteliği kullanma{{}}


11
doğru, ancak örneğiniz, $ routeChangeSuccess öğesinde $ kapsam değişkenleri tarafından parametrelendirilen başlığın nasıl değiştirileceğini göstermez. Böylece ayarlayabilirsiniz title = "Blog"ama ayarlayamazsınız title = '{{"Blog post " + post.title}}'.
Eric Drechsel

10
@felix current.titleayrıca
şununla

8
$ rootScope.title = geçerli. $ route.title; doble olmadan $$
david.sansay

7
Sadece Angular sürümümün birkaç sürümünü (1.0.5 - 1.2.7) yükselttim ve bu kodum için beni kırdı. Ben kullanıyordum current.$routeeski kodunda ve çalışıyordu. Yükseltme ile, rota üzerinde çift $ gerekir. current.$$route
Tyler Forsythe

6
Cevaplayıcıda ne zaman görebilirsiniz '/Product/:id'. :idBu yöntemle değere sahip olmanın herhangi bir yolu var mı? Denedim title: function(params){return params.id;}ama çalışmıyor ... Belki kullanıyor resolve?
mickaelb91

190

Ayrıca başlığı doğrudan javascript ile ayarlayabileceğinizi unutmayın.

$window.document.title = someTitleYouCreated;

Bu veri bağlama yoktur, ancak koyarak zaman yeterli ng-appyer <html>etiketi problemlidir. (Örneğin, <head>tam olarak tek bir yerde tanımlanmış olan JSP şablonlarını kullanarak , ancak birden fazla uygulamanız var.)


5
Benim için Internet Explorer üzerinde çalışmanın tek yolu buydu, diğer yöntemler de diğer tarayıcılarda çalıştı
Maarten

4
Maarten belirtildiği gibi bu sadece IE7 ve IE8 bu işleri yaklaşım olduğunu
soymak

33
İnsanların geri adım
atmadığı

7
Inanılmaz. Bu, diğerlerinin bahsettiği tüm maskaralıklardan çok daha basitti. Teşekkürler!
Leonard Teo

8
Düz 'pencere' kullanmak iyidir - bu doğrudan DOM üzerinde etkili olur. '$ window' açısal bir şeydir ve onu kullanmak için enjekte etmeniz gerekir. Her iki şekilde de çalışır.
broc.seib

119

Bildirmek ng-appüzerinde htmleleman hem kök kapsamını sağlar headve body.

Bu nedenle kontrolörünüze enjekte edin $rootScope bir başlık özelliği ve ayarlayın:

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

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

ve sayfanızda:

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

8
benim görüşüme en iyi cevap. Kabul edilen cevapta açıklandığı gibi ng-app seviyesinde bir kontrolörün olması bu durumda işe yaramaz.
Nicolas Janel

1
Bu çözümün ne kadar hafif olduğunu seviyorum ve $$ özelliklerini kullanmaktan kaçınıyor
tedwards947

Kabul edilen cevap gereksiz komplikasyon ve riskler ekler. Bu sürüm, bir değişken ayarlamak kadar basit hale getirir.
special0ne

3
$ RootScope'u kullanmaya hazırsanız, en azından bunu bir servise çıkarırsınız, böylece kontrol cihazınızda $ rootScope olmaz.
Michael J. Calkins

3
Bu çözümü kullanmak istiyorum ama kullanmanın avantajlarının ne olduğunu merak ediyorum document.title = "App";
remarsh

43

Angularjs-viewhead modülü , başlığı yalnızca özel bir yönerge kullanarak görüntüleme başına esasına göre ayarlamak için bir mekanizma gösterir.

İçeriği zaten görünüm başlığı olan mevcut bir görünüm öğesine uygulanabilir:

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

... veya bağımsız bir öğe olarak kullanılabilir; bu durumda öğe, oluşturulan belgede görünmez olur ve yalnızca görünüm başlığını ayarlamak için kullanılır:

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

Bu direktifin içeriği, kök kapsamda olduğu gibi viewTitle, diğer herhangi bir değişken gibi başlık öğesinde kullanılabilir:

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

Kök kapsamını "görebilen" başka herhangi bir noktada da kullanılabilir. Örneğin:

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

Bu çözüm, başlığın sunumun geri kalanını kontrol etmek için kullanılan mekanizma ile ayarlanmasına izin verir: AngularJS şablonları. Bu, bu sunum mantığı ile denetleyicileri dağınık hale getirme ihtiyacını ortadan kaldırır. Kontrolörün bilgilendirmek için kullanılacak tüm verileri hazır bulundurması gerekir , başlığı sunması gerekir, ancak şablon, nasıl sunulacağı konusunda son kararlılığı yapar ve kapsam verilerini normal olarak bağlamak için ifade enterpolasyonunu ve filtreleri kullanabilir.

(Feragatname: Bu modülün yazarıyım, ancak burada sadece bu sorunu çözmesi için başka birine yardımcı olacağı umuduyla atıfta bulunuyorum.)


4
Bu çözümün daha fazla değerlendirilmediğine inanamıyorum. Diğerlerinin çoğu gerçekten kötü tasarım seçimleridir.
Martin Wawrusch

Kabul ettim, bu en iyi çözüm olmalı. Bunu, başlığı ayarlamak için sayfa düzeyinde bir denetleyici bildirmekten çok daha iyi seviyorum. Bilginize: bunu Açısal v1.3.2 ve açısal yol segmenti v1.3.3 ile kullanmak ve bir cazibe gibi çalışıyor.
Nate Barbettini

Bu çözümü onaylıyorum;)
jkoreska

3
Burada blogumda angularjs-viewhead ve ilgili başka bir fikir hakkında biraz daha yazdım: görünüşe göre
Martin Atkins

Aynı görünümü üst düzey ve alt düzey görünümde yeniden kullanıyorsanız, bir ng-if ile görünüm başlığını kullanabilirsiniz, örneğin: <h4 ng-if = "$ state.includes ('some-state')" view-title> {{...}} </h4> <h4 ng-if = "! $ state.includes ('some-state')"> {{...}} </ h4 ile ilgili ayrıntılar >
anre

32

İşte kaynağa özgü sayfa başlıklarını ayarlamak için $ rootScope'un denetleyicilere enjekte edilmesini gerektirmeyen benim için çalışan uyarlanmış bir çözüm.

Ana şablonda:

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

Yönlendirme yapılandırmasında:

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

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

Ve çalışma bloğunda:

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

Sonunda kontrolörde:

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

1
. ProductController ($ scope.page.setTitle) başlık seti $ 'routeChangeSuccess $' (üzerinde $ rootScope tarafından geçersiz ediliyor $ rootScope varsayılan bir başlık ayarlama $ üzerinde ( '$ routeChangeStart' bu açıdan daha güvenlidir...
Kristo Aun

@ mr-hash: Burada önerdiğim küçük ayar, birçok rotaya sahip, ancak başlıksız mevcut açısal projeler için mükemmel. Rotada herhangi bir başlık tanımlanmamışsa, denetleyicinin adından başlık üretecektir:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
mikhail-t

1
çıktıyı şu şekilde sterilize etmeyi unutmayın:this.title = title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ') + ' | Site Name';
Henrik Stenbæk

Tanımlanamayan bir hata aldım, bu yüzden son biti şu şekilde değiştirdim: $ rootScope.page.title = current. $$ route? geçerli. $$ route.title + '| Site Adı ':' Site Adı ';
Andy

15

Başlıkları önceden biliyorsanız, jkoreska'nın çözümü mükemmeldir, ancak başlığı bir kaynaktan aldığınız verilere göre ayarlamanız gerekebilir.

Çözümüm için tek bir hizmet gerekiyor. RootScope tüm DOM öğelerinin temelini oluşturduğundan, html öğesine bir kullanıcı gibi bir denetleyici koymamız gerekmez

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

Başlığı değiştirmeniz gereken tüm denetleyiciler

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

küçük bir sorun, bir sayfayı yenilediğinizde, sekme adınızda '{{title}}' görürsünüz ve sayfa oluşturulduktan sonra yalnızca 'Bazı Başlık' görürsünüz. fabrika ile çözüm bu davranışa sahip değil
Dmitri Algazin

5
bunun yerine {{title}}kullanınng-bind='title'
Faradox

1
@Faradox ... ile anlaşın ng-bind, önceden enterpolasyonlu sözdiziminin başlık gerçekten değerlendirilmeden önce görüntülenmesini engeller. +100
Seth

11

Başlık veya meta açıklamanın dinamik olarak ayarlanmasına izin veren temiz bir yol. Örneğin ui-router kullanıyorum ama ngRoute'u aynı şekilde kullanabilirsiniz.

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

Alternatif olarak, ui-yönlendirici kullanıyorsanız :

index.html

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

Yönlendirme

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

2
Bu işe yarayamıyorum .. ui-routerDurumuma dayalı URL ve içerik güncelleme var ve hiçbir hata veya uyarı almak, ancak devlet yapılandırma nesnesinin herhangi bir bölümüne üzerinden erişemiyorum gibi görünüyor $state.current.[...]. Bunu ui-routeryapmak için hangi sürümünü kullandınız?

Cevaba yapılan "Çalışma Zamanı Yapılandırması" düzenlemem, yukarıdaki yorumumda bahsettiğim sorunu çözüyor. :) Bunu yapmanın daha iyi bir yolu varsa fikirlere açığım.

bu benim için çalışmıyor ve 'başlık' API belgelerinde bulunamadı - bu hala destekleniyor mu?
GraehamF

7

Özel etkinlik tabanlı çözüm

İşte burada (bu yazıdan itibaren) başkaları tarafından belirtilmeyen başka bir yaklaşım.

Bunun gibi özel etkinlikleri kullanabilirsiniz:

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

Bu yaklaşımın avantajı, başlığı ayarlaması gereken her denetleyiciye yazılması ve daha sonra enjekte edilmesini gerektirmemesi ve ayrıca (ab) 'yi kullanmamasıdır $rootScope. Ayrıca, yönlendiricinin yapılandırma nesnesindeki özel veri özniteliklerini (en azından bildiğim kadarıyla) kullanarak mümkün olmayan bir dinamik başlık (kod örneğinde olduğu gibi) ayarlamanıza olanak tanır.


5

titleEtiketi içeren bir ngApp'a sahip olmadığınız senaryolar için, pencere başlığını ayarlaması gereken denetleyicilere bir hizmet enjekte edin.

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

Çalışma örneği ... http://jsfiddle.net/8m379/1/


5

Başlık öğesi üzerinde kontrolünüz yoksa (asp.net web formu gibi) burada kullanabileceğiniz bir şey var

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

Kullanarak basit ve kirli yolu $rootScope:

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

Denetleyicilerinizde, başlığı oluşturmak için gerekli verilere sahip olduğunuzda şunları yapın:

$rootScope.title = 'Page X'

4

Bu cevapların hiçbiri yeterince sezgisel görünmedi, bu yüzden bunu yapmak için küçük bir direktif oluşturdum. Bu şekilde, sayfadaki başlığı normalde nerede yapacağınızı bildirmenize olanak tanır ve dinamik olmasını da sağlar.

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

Elbette modül adını kendinizinkine uyacak şekilde değiştirmeniz gerekecektir.

Bunu kullanmak için, normal bir <title>etikette yaptığınız gibi bunu görünümünüze atın :

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

Ayrıca, dinamik olarak ihtiyacınız yoksa düz metin de ekleyebilirsiniz:

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

Alternatif olarak, bir özelliği daha IE dostu yapmak için kullanabilirsiniz:

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

Açısal kod da dahil olmak üzere, tablonun etiketine istediğiniz metni koyabilirsiniz. Bu örnekte,$scope.titleText özel başlık etiketinin hangi denetleyicide olduğu denetlenecektir.

Sayfanızda birden fazla sayfa başlığı etiketi olmadığından emin olun, aksi takdirde birbirlerini tıkayacaktır.

Plunker örneği burada http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV . Başlık değişikliğini görmek için zip dosyasını indirmeniz ve yerel olarak çalıştırmanız gerekir.


Benzer bir şey buldum. Şimdiye kadar kullanımı en sezgiseldir ve bir denetleyici takmayı gerektirmez html. Yönergemde ayrıca isteğe bağlı bir pageTitlePrefixsabit enjekte ediyorum .
z0r

4

Açısal UI yönlendirici için basit çözüm:

HTML:

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

App.js> myApp.config bloğu

$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

Başlık değişiklikleri yapmanın farklı bir yolu. Belki bir fabrika işlevi kadar ölçeklenebilir değil (muhtemelen sınırsız sayfalarla başa çıkabilir) ama anlaması daha kolaydı:

Benim index.html böyle başladı:

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

Sonra "nav.html" adlı kısmi yaptım:

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

Sonra "index.html" geri döndü ve ng-include ve kısmi benim için ng-view kullanarak nav.html ekledi:

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

Ng-cloak fark ettiniz mi? Bu cevapla bir ilgisi yok ama yükleme tamamlanıncaya kadar sayfayı gizliyor, hoş bir dokunuş :) Nasıl yapacağınızı buradan öğrenebilirsiniz: öğren Angularjs - ng-cloak / ng-show elemanları yanıp sönüyor

İşte temel modül. "App.js" adlı bir dosyaya koydum:

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

}());

Modülün sonuna doğru bakarsanız, aşağıdakilere dayalı bir yaratık ayrıntı sayfam olduğunu göreceksiniz: id. Çıtır Yaratıklar sayfasında kullanılan bir kısmi. [Corny, biliyorum - belki de her türlü tavuk külçesini kutlayan bir site;) Her neyse, bir kullanıcı herhangi bir bağlantıyı tıkladığında başlığı güncelleyebilirsin, bu yüzden yaratık ayrıntı sayfasına giden ana Çıtır Yaratıklar sayfamda, tıpkı yukarıdaki nav.html'de gördüğünüz gibi $ root.title güncellemesinin gideceği yer:

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

Üzgünüm çok rüzgarlı ama çalıştıracak kadar detay veren bir yazı tercih ederim. AngularJS belgelerindeki örnek sayfanın güncel olmadığını ve ng-bind şablonunun 0.9 sürümünü gösterdiğini unutmayın. Bunun o kadar da farklı olmadığını görebilirsiniz.

Sonradan düşünülmüş: bunu biliyorsunuz ama herkes için burada; index.html dosyasının alt kısmında, app.js modülünü içermelidir:

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

2
Bence bunu kullanma. Görünümlerde (sunum) verileri (bilgileri) karıştırıyorsunuz. Daha sonra, görünümün çeşitli yerlerinde mevcut olabilecek HTML bağlantılarınızın her tarafına dağılmış başlık kaynaklarını bulmak çok zor olacaktır ..
amit bakle

Başlık yalnızca gerçekte bir bağlantı tıklandığında güncellendiğinden , kullanıcı bir sayfaya ilk kez geldiğinde veya kullanıcı yenilendiğinde bu başlık doğru şekilde ayarlanmaz.
Mark Amery

3

Bunu çözmek zorunda kaldığımda ng-app, sayfanın htmletiketine yerleştiremedim, bu yüzden bir hizmetle çözdüm:

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

Michael Bromley'den ilham alan Özel Etkinlik Tabanlı çözüm

$ Scope ile çalışmasını sağlayamadım, bu yüzden rootScope ile denedim, belki biraz daha kirli ... (özellikle olayı kaydetmeyen sayfada bir yenileme yaparsanız)

Ama işlerin nasıl gevşek bir şekilde eşleştirildiği fikrini gerçekten seviyorum.

1.6.9 angularjs kullanıyorum

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>

Benim için çalışıyor :)



1

Diğerleri daha iyi yöntemlere sahip olsa da, görünümlerimin / şablonların her birinin ayrı bir denetleyicisi olduğundan, $ rootScope'u denetleyicilerimde kullanabildim. Her denetleyiciye $ rootScope enjekte etmeniz gerekir. Bu ideal olmasa da, benim için çalışıyor, bu yüzden geçmem gerektiğini düşündüm. Sayfayı incelerseniz, başlık etiketine ng-bağlayıcı ekler.

Örnek Denetleyici:

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

Örnek Index.html üstbilgisi:

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

PageTitle ve pageDescription öğelerini bir REST çağrısından veri döndürmek gibi dinamik değerlere de ayarlayabilirsiniz:

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

Yine, başkalarının buna nasıl yaklaşılacağı konusunda daha iyi fikirleri olabilir, ancak bir ön işleme kullandığım için, ihtiyaçlarım karşılanıyor.


0

Çözümü için tosh shimayama'ya teşekkürler .
Bir hizmeti doğrudan içine koymak o kadar temiz olmadığını düşündüm $scope, işte bu konuda benim küçük varyasyon: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

Denetleyici (orijinal yanıtta bana biraz fazla aptal gibi geldi) bir ActionBar nesnesi yaratıyor ve bu da $ scope içine doldurulmuş.
Nesne, hizmeti gerçekten sorgulamaktan sorumludur. Ayrıca , şablon URL'sini ayarlama çağrısını $ kapsamından gizler , bunun yerine URL'yi ayarlamak için diğer denetleyicilerin kullanımına sunulur.


0

Sayın Hash şu ana kadar en iyi cevaba sahipti, ancak aşağıdaki çözüm aşağıdaki faydaları ekleyerek (benim için) onu ideal hale getiriyor:

  • Saatleri yavaşlatır, bu da işleri yavaşlatabilir
  • Aslında kontrolörde ne yapmış olabileceğimi otomatikleştiriyor
  • Hala istiyorsam denetleyiciden hala erişim sağlıyor.
  • Ekstra enjeksiyon yok

Yönlendiricide:

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

Çalışma bloğunda:

.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

Bulduğum en iyi ve dinamik çözüm, değişken değişiklikleri izlemek ve ardından başlığı güncellemek için $ watch kullanmaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.