我使用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"; }

当前回答

angular-ui-router的简单解决方案:

HTML:

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

myApp. js >。配置块

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

其他回答

一个干净的方式,允许动态设置标题或元描述。在示例中,我使用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>
...

模块angularjs-viewhead展示了一种机制,它只使用自定义指令在每个视图的基础上设置标题。

它可以应用于一个已经存在的视图元素,其内容已经是视图标题:

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

...或者它可以作为一个独立的元素使用,在这种情况下,元素将在呈现的文档中不可见,只用于设置视图标题:

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

这个指令的内容在根作用域中作为viewTitle可用,所以它可以像其他变量一样用于title元素:

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

它还可以用于任何其他可以“看到”根作用域的位置。例如:

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

这个解决方案允许通过与控制演示的其他部分相同的机制来设置标题:AngularJS模板。这避免了用这种表示逻辑使控制器混乱的需要。控制器需要提供用于通知标题的任何数据,但模板最终决定如何表示它,并且可以像往常一样使用表达式插值和过滤器绑定范围数据。

(免责声明:我是这个模块的作者,但我在这里引用它只是希望它能帮助其他人解决这个问题。)

你可以在<html>级别定义controller。

 <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

这些答案似乎都不够直观,所以我创建了一个小指令来做这件事。这种方式允许您在页面中声明标题,而通常情况下是这样做的,并允许它是动态的。

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。无论自定义标题标签当前在哪个控制器中。

只要确保你的页面上没有多个页面标题标签,否则它们会互相攻击。

这里的Plunker例子http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV。您必须下载压缩文件并在本地运行,才能看到标题的变化。

如果你事先知道标题,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");
});