AngularJS部分ビューに基づいてヘッダーを動的に変更するにはどうすればよいですか?


411

AngularJSの部分ビューを含めるためにng-viewを使用しており、含まれているビューに基づいてページタイトルとh1ヘッダータグを更新したいと思います。ただし、これらは部分的なビューコントローラーの範囲外であるため、コントローラーのデータセットにバインドする方法を理解できません。

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>

私のJavaScript:

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メタ変数を変更するだけです。
KamuranSönecek16年

回答:


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
ストレート$スコープにサービスを置くことを考慮すればuhmm ...私はわからない素敵な AngularJSアーキテクチャインチ おそらく$ scopeにコントローラー関数を入れてから、この関数にサービスを照会させる方が良いでしょう。
superjos 2013年

11
この例は素晴らしいものでした。ただ1つのフォローアップがありますが、最初のロード時に、タイトルに{{Page.title()}}テキストが表示されます(非常に速く)。ng-cloakは本体にないので使えないと思います。これを回避するための提案はありますか?
Arthur Frankel 2013年

52
@ArthurFrankel ng-bindを使用するだけ(例:ng-bind = "Page.title()")
Pius Uzamere

2
または、コントローラーをタイトルタグで指定できます。htmlヘッダーにグローバルコントローラーは必要ありません:<title ng-controller = "titleCtrl"> {{Page.title()}} </ title>
Dmitri Algazin

6
個人的$rootScopeには、追加のコントローラーを作成するのではなく、タイトルを設定することを好みます。
DDA 2014

634

ルーティングを使用している場合にページタイトルを設定するための素晴らしい方法を発見しました。

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

編集ng-bindカーリーの代わりに属性を使用して、{{}}ロード時に表示されないようにします


11
右ですが、あなたの例では、$ scope変数によってパラメーター化された$ routeChangeSuccessのタイトルを変更する方法を示していません。@ toshの例では、Pageサービスを使用しています。したがって、設定はできますができtitle = "Blog"ませんtitle = '{{"Blog post " + post.title}}'
Eric Drechsel 2013年

10
@felix current.titleも同様にタイトルにアクセスできます
Eldelshell '18 / 07/18

8
$ rootScope.title = current。$ route.title; ドーブルなし$$
david.sansay 2013

7
Angularのバージョンをいくつかのバージョン(1.0.5から1.2.7)にアップグレードしたところ、コードが壊れてしまいました。私はcurrent.$route古いコードで使用しており、それは機能していました。アップグレードでは、ルート上の二重の$が必要です。current.$$route
タイラーフォーサイス

6
answserでいつ見ることができます'/Product/:id'。持っているどのような方法があり:id、この方法での値は?試しましたtitle: function(params){return params.id;}が動作しません...たぶんresolve
mickaelb91 14

190

また、JavaScriptを使用してタイトルを直接設定することもできます。

$window.document.title = someTitleYouCreated;

これにはデータバインディングはありませんがng-app<html>タグを配置するのに問題がある場合はこれで十分です。(たとえば<head>、が1か所で定義されているJSPテンプレートを使用していても、アプリが複数ある場合。)


5
これが私にとってInternet Explorerで動作する唯一の方法でしたが、他の方法は他のブラウザーでも動作しました
Maarten

4
マールテンが述べたように、これはie7およびie8で機能する唯一のアプローチです
rob

33
人々がどのように後退して、スコープとファクトリーなしでこのことをいかに簡単に行うことができるかを驚くべきこと
redben

7
信じられない。これは、他の人が言及していたすべての悪意よりもはるかに単純でした。ありがとう!
Leonard Teo 2014年

8
プレーンな「ウィンドウ」を使用しても問題ありません。これは、DOMに直接作用します。「$ window」は角張ったものであり、使用するにはそれを注入する必要があります。どちらの方法でも機能します。
broc.seib 2014

119

宣言ng-apphtml要素は両方のルートスコープを提供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
私の意見で最良の答え。受け入れられた回答に記載されているようにng-appレベルのコントローラーを持っていることは、この場合は役に立ちません。
Nicolas Janel 2014年

1
このソリューションがいかに軽量で、$$プロパティの使用を避けているのが好きです
tedwards947

受け入れられた答えは、不必要な複雑さとリスクを追加します。このバージョンでは、変数の設定と同じくらい簡単です。
special0ne 2014年

3
$ rootScopeの使用に夢中になっている場合は、少なくともこれをサービスに抽出して、コントローラーに$ rootScopeがないようにします。
Michael J. Calkins 14

3
このソリューションを使用したいのですが、それを使用する利点が何よりも優れていることに興味がありdocument.title = "App"ます。
2014

43

angularjs-viewheadモジュールは、カスタムディレクティブのみを使用して、ビューごとにタイトルを設定するメカニズムを示しています。

コンテンツが既にビュータイトルである既存のビュー要素に適用することもできます。

<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
このソリューションはこれ以上賛成されていないとは信じられません。他のほとんどのものは本当に悪いデザインの選択です。
Martin Wawrusch 2014

同意された、これはトップのソリューションでなければなりません。これは、タイトルを設定するためにページレベルでコントローラーを宣言するよりもずっと好きです。参考までに、これをAngular v1.3.2およびangular-route-segment v1.3.3で使用すると、魅力的なように動作します。
Nate Barbettini 14

私はこの解決策を支持します;)
jkoreska 2015

3
私はangularjs-viewheadと私のブログに、ここで別の関連考え方について少し書きました:apparently.me.uk/angularjs-view-specific-sidebars
マーティン・アトキンス

トップレベルとサブレベルのビューで同じビューを再利用する場合でも、ng-ifでview-titleを使用できます。例:<h4 ng-if = "$ state.includes( 'some-state')" view-title> {{...}}の詳細</ h4> <h4 ng-if = "!$ state.includes( 'some-state')"> {{...}} </ h4の詳細>
2016年

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でタイトルセット($ scope.page.setTitle)は$ rootScopeによって上書きされている$( '$ routeChangeSuccess'に$ rootScopeにデフォルトのタイトルを設定する$( '$ routeChangeStart'に関するこの点で安全です。。。。
クリスト・アウン

@ mr-hash:これは私が提案する小さな調整です。多くのルートを持つ既存の角度のあるプロジェクトに最適ですが、タイトルはありません。タイトルがルート上に定義されていない場合は、コントローラの名前からタイトルを生成します:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
ミハイル・トン

1
:このようなサニタイズ出力に覚えているthis.title = title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ') + ' | Site Name';
ヘンリックStenbæk

未定義のエラーが発生したため、最後のビットを$ rootScope.page.title = current。$$ route?に変更しました。current。$$ route.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");
});

小さな問題、ページを更新すると、タブ名に「{{title}}」が表示され、ページがレンダリングされた後、「Some Title」のみが表示されます。工場でのソリューションにはそのような動作はありません
Dmitri Algazin 2014年

5
代わりに{{title}}使用ng-bind='title'
Faradox

1
@Faradox ...に同意するとng-bind、タイトルが実際に評価される前に、事前に補間された構文が表示されなくなります。+100
Seth

11

タイトルまたはメタ説明を動的に設定できるクリーンな方法。例ではui-routerを使用していますが、ngRouteも同様に使用できます。

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

または、ui-routerを使用している場合:

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を行うためにどのバージョンを使用しましたか?

回答に対する「実行時構成」編集は、上記のコメントで述べた問題を解決します。:)これを行うためのより良い方法があれば、私はアイデアを受け入れます。

これは私にとっては機能せず、APIタイトルに「タイトル」が見つかりません-これはまだサポートされていますか?
GraehamF 2016年

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

このアプローチには、追加のサービスを記述してタイトルを設定する必要のあるすべてのコントローラーに注入する必要がなく、さらにを使用しないという利点があります$rootScope。また、(コード例のように)動的なタイトルを設定することもできます。これは、ルーターの構成オブジェクトでカスタムデータ属性を使用することはできません(少なくとも私が知る限り)。


5

titleタグを含むngAppがないシナリオでは、ウィンドウタイトルを設定する必要があるコントローラーにサービスを注入するだけです。

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 Webフォームなど)を制御できない場合は、次の方法を使用できます。

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>

もちろん、Angularコードを含め、必要なテキストをタグに入れることができます。この例では$scope.titleText、カスタムタイトルタグが現在あるコントローラーを検索します。

ページに複数のpage-titleタグがないことを確認してください。そうしないと、タグが相互に干渉します。

ここにhttp://plnkr.co/edit/nK63te7BSbCxLeZ2ADHVの Plunkerの例があります。タイトルの変更を確認するには、zipをダウンロードしてローカルで実行する必要があります。


私は似たようなものを思いつきました。非常に直感的に使用でき、コントローラをに置く必要はありませんhtml。私のディレクティブでは、オプションのpageTitlePrefix定数も注入しています。
z0r 2015年

4

angular-ui-routerの単純なソリューション:

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」に戻り、パーシャルのng-includeとng-viewを使用してnav.htmlを追加しました。

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

ng-cloakに注意してください。それはこの答えとは何の関係もありませんが、読み込みが完了するまでページを非表示にします。素敵なタッチです:)ここで方法を学んでください: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"});
    });

}());

モジュールの終わりを見ると、:idに基づくクリッター詳細ページがあることがわかります。Crispy Crittersのページで使用されているパーシャルです。[Corny、わかっています-多分それはあらゆる種類のチキンナゲットを祝うサイトです;)とにかく、ユーザーがリンクをクリックしたときにタイトルを更新できます。上記のnav.htmlで見たように、ここで$ root.titleの更新が行われます。

<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バージョンのng-bind-templateを示していることに注意してください。それほど大きな違いはないことがわかります。

後から考える:あなたはこれを知っていますが、他の人のためにここにあります。index.htmlの下部に、モジュールを含むapp.jsを含める必要があります。

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

2
私の意見では、これを使用しないでください。ビュー(プレゼンテーション)でデータ(情報)を混合しています。その後、...タイトル源は、ビュー内のさまざまな場所に存在することができるあなたのHTMLリンクを介してすべてを散乱見つけることは非常に難しいだろうに
アミットbakle

タイトルは実際にリンクをクリックしたときのみ更新されるため、ユーザーが最初にページにアクセスしたとき、またはユーザーが更新したときに、タイトルが正しく設定されません。
Mark Amery、2015年

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

Michael Bromleyから発想を得たカスタムイベントベースのソリューション

$ scopeで機能させることができなかったので、rootScopeを試してみましたが、おそらくもう少しダーティです...(特に、イベントを登録しないページで更新を行う場合)

しかし、私は物事が疎結合されている方法のアイデアが本当に好きです。

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を挿入する必要があります。これは理想的ではないかもしれませんが、私には機能しているので、私はそれを渡す必要があると考えました。ページを検査すると、ng-bindingがタイトルタグに追加されます。

コントローラーの例:

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>

また、pageTitleとpageDescriptionを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の解決に感謝します。
にサービスを直接配置するのはそれほどクリーンではないと思ったので$scope、そのわずかなバリエーションを以下に示します。http//plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

コントローラー(元の答えでは少しおかしいように思えました)がActionBarオブジェクトを作成し、これが$ scopeに詰め込まれます。
オブジェクトは、サービスへの実際のクエリを担当します。また、テンプレートのURLを設定するための呼び出しを$ scopeから隠します。代わりに、他のコントローラーがURLを設定するために使用できます。


0

これまでのところHash氏が最良の答えを出しましたが、以下の解決策は、次の利点を追加することで理想的です(私にとって)。

  • 時計を追加しないため、動作が遅くなる可能性があります
  • 実際にコントローラーで行ったことを自動化しますが、
  • それでも必要な場合は、コントローラからアクセスできます。
  • 余分な注射なし

ルーターで:

  .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

私が見つけたより優れた動的なソリューションは、$ watchを使用して変数の変更を追跡し、タイトルを更新することです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.