AngularJS 부분보기를 기반으로 헤더를 동적으로 변경하는 방법은 무엇입니까?


411

ng-view를 사용하여 AngularJS 부분보기를 포함하고 있으며 포함 된보기를 기반으로 페이지 제목과 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 메타 변수 만 변경하면됩니다.
Kamuran Sönecek

답변:


342

<html>레벨 에서 컨트롤러를 정의 할 수 있습니다.

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

service :를 작성 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에 Controller 함수를 넣은 다음이 함수가 서비스를 쿼리하도록하는 것이 좋습니다.
superjos

11
이 예는 훌륭했습니다. 후속로드가 있지만 초기로드시 제목에 {{Page.title ()}} 텍스트가 표시됩니다 (매우 빠름). ng-cloak은 몸에 없기 때문에 사용할 수 없다고 생각합니다. 이것을 피하기 위해 어떤 제안?
Arthur Frankel

52
겨 바인드 @ArthurFrankel 그냥 사용 (예 : NG-바인드 = "Page.title ()")
비오 Uzamere

2
또는 우리는 제목 태그에 컨트롤러를 지정할 수 있습니다, HTML 헤더에 글로벌 컨트롤러에 대한 필요가 없습니다 : <제목 겨 컨트롤러 = "titleCtrl"> {{Page.title ()}} </ 제목>
드미트리 Algazin

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-bindcurls 대신 속성을 사용하여 {{}}로드시 표시되지 않음


11
그러나 귀하의 예는 $ scope 변수로 매개 변수화 된 $ routeChangeSuccess에서 제목을 변경하는 방법을 보여주지 않습니다. 따라서 설정할 수는 title = "Blog"있지만 설정할 수는 없습니다 title = '{{"Blog post " + post.title}}'.
Eric Drechsel

10
@felix 당신 current.title도 같은 제목에 액세스 할 수 있습니다
Eldelshell

8
$ rootScope.title = current. $ route.title; doble없이 $$
david.sansay

7
방금 Angular 버전을 여러 버전 (1.0.5에서 1.2.7으로) 업그레이드했는데 코드에서 문제가 발생했습니다. current.$route이전 코드에서 사용 하고 있었고 작동했습니다. 업그레이드를 위해서는 이중 $ on route가 필요합니다. current.$$route
Tyler Forsythe

6
답변에서 언제 볼 수 있습니다 '/Product/:id'. 이 방법으로 :id가치를 얻는 방법이 있습니까? 시도 title: function(params){return params.id;}했지만 작동하지 않습니다 resolve.
mickaelb91

190

자바 스크립트로 제목을 직접 설정할 수도 있습니다. 즉,

$window.document.title = someTitleYouCreated;

이것은 데이터 바인딩을 가지고 있지 않지만, 퍼팅 때 충분 ng-app<html>태그하는 것은 문제가있다. 예를 들어 <head>정확히 한 곳에 정의 된 JSP 템플리트를 사용 하지만 둘 이상의 앱이 있습니다.


5
이것이 나를 위해 Internet Explorer에서 작동하게하는 유일한 방법이었습니다. 다른 방법은 다른 브라우저에서도 작동했습니다.
Maarten

4
Maarten이 언급했듯이 이것은 ie7 및 ie8에서 작동하는 유일한 접근 방법입니다.
rob

33
사람들이
물러서지

7
믿을 수 없는. 이것은 다른 사람들이 언급 한 모든 shenanigans보다 훨씬 간단했습니다. 감사!
레너드 테오

8
일반 '창'을 사용하는 것이 좋습니다. DOM에 직접 작용합니다. '$ window'는 각진 것이므로 그것을 사용하려면 주입해야합니다. 어느 쪽이든 작동합니다.
broc.seib

119

선언 ng-apphtml요소 것은 모두를위한 루트 범위 제공 headbody.

따라서 컨트롤러에서 다음 $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

1
나는이 솔루션이 얼마나 경량 사랑, 그리고 $$ 속성을 사용 방지
tedwards947을

허용되는 답변은 불필요한 합병증과 위험을 추가합니다. 이 버전은 변수를 설정하는 것만 큼 간단합니다.
special0ne

3
$ rootScope를 사용하지 않으면 적어도 서비스로 추출하여 컨트롤러에 $ rootScope가 없습니다.
Michael J. Calkins

3
이 솔루션을 사용하고 싶지만이 솔루션의 장점이 무엇인지 궁금합니다 document.title = "App".
remarsh

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

동의, 이것이 최고의 솔루션이어야합니다. 제목을 설정하기 위해 페이지 수준에서 컨트롤러를 선언하는 것보다 훨씬 좋습니다. 참고 : Angular v1.3.2 및 angular-route-segment v1.3.3과 함께 사용하면 매력처럼 작동합니다.
Nate Barbettini

나는이 해결책을 추천한다;)
jkoreska

3
나는 내 블로그에 angularjs-viewhead 및 다른 관련 아이디어에 대해 조금 더 썼다 : 겉보기
Martin Atkins

최상위 및 하위 수준에서 동일한보기를 재사용하는 경우 여전히 ng-if와 함께보기 제목을 사용할 수 있습니다 (예 : <h4 ng-if = "$ state.includes ( 'some-state')"). view-title> {{...}}에 대한 세부 사항 </ h4> <h4 ng-if = "! $ state.includes ( 'some-state')"> {{...}}에 대한 세부 사항 </ h4 >
anre

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. $ on ( '$ routeChangeSuccess'에 의해 재정의됩니다. $ rootScope. $ on ( '$ routeChangeStart')에 기본 제목을 설정하는 것이이 점에서 더 안전합니다.
Kristo Aun

@ mr-해시 : 여기에 작은 조정이 있습니다. 많은 경로가 있지만 제목이없는 기존 각도 프로젝트에 적합합니다. 경로에 제목이 정의되어 있지 않으면 컨트롤러 이름에서 제목을 생성합니다.$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';
헨릭 Stenbæk

정의되지 않은 오류가 발생하여 마지막 비트를 $ rootScope.page.title = current. $$ route? current. $$ route.title + '| 사이트 이름 ':'사이트 이름 ';
Andy

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}}'이 표시되고 페이지가 렌더링 된 후 '일부 제목'만 표시됩니다. 공장 솔루션에는 그 행동이 없습니다
Dmitri Algazin

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 문서에서 'title'을 찾을 수 없습니다. 여전히 지원됩니까?
GraehamF

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 웹 양식)를 제어 할 수없는 경우 사용할 수있는 항목

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 현재 사용자 정의 제목 태그가있는 컨트롤러를 .

페이지에 여러 페이지 제목 태그가 없는지 확인하십시오. 그렇지 않으면 서로 충돌 할 수 있습니다.

플 런커 예제는 여기 http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV 입니다. 타이틀 변경 사항을 보려면 zip을 다운로드하여 로컬로 실행해야합니다.


나는 비슷한 것을 생각해 냈습니다. 지금까지 사용하기 가장 직관적이며 컨트롤러를 장착 할 필요가 없습니다 html. 내 지시어에도 선택적 pageTitlePrefix상수를 주입합니다 .
z0r

4

각도 UI 라우터를위한 간단한 솔루션 :

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 쇼 요소 깜박임

기본 모듈은 다음과 같습니다. "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를 기반으로 한 critter-detail 페이지가 있음을 알 수 있습니다. Crispy Critters 페이지에서 사용되는 부분입니다. [코니, 알아요-아마 모든 종류의 치킨 너겟을 기념하는 사이트 일 것입니다.) 어쨌든, 사용자가 링크를 클릭 할 때 제목을 업데이트 할 수 있습니다. 위의 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 링크 전체에 흩어져있는 제목 소스를 찾기가 매우 어려울 것입니다.
amit bakle

제목은 실제로 링크를 클릭 할 때만 업데이트 되므로 사용자가 페이지를 처음 방문하거나 새로 고침 할 때 제목이 올바르게 설정되지 않습니다.
Mark Amery

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 shimayama 에게 감사합니다 .
나는로 서비스를 똑바로 넣어 너무 깨끗하지라고 생각 $scope때문에 여기에 내 약간의 변화입니다 : http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

컨트롤러 (원래 답변에서 약간 바보 같은 것처럼 보임)는 ActionBar 객체를 만들고이 객체는 $ scope에 채워집니다.
객체는 실제로 서비스를 쿼리합니다. 또한 $ scope에서 템플릿 URL을 설정하는 호출을 숨기고 대신 다른 컨트롤러가 URL을 설정하는 데 사용할 수 있습니다.


0

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