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

当前回答

如果你不能控制标题元素(如asp.net web form),这里有一些东西你可以使用

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

其他回答

感谢岛山托什的解决方案。 我认为直接将服务放入$作用域不太干净,因此这里是我对它的轻微更改:http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

控制器(在最初的回答中,我觉得有点太笨了)创建了一个ActionBar对象,这个对象被填充到$scope中。 对象负责实际查询服务。它还从$作用域中隐藏了设置模板URL的调用,而其他控制器可以使用该调用来设置URL。

注意,您也可以直接使用javascript设置标题,即,

$window.document.title = someTitleYouCreated;

这没有数据绑定,但当把ng-app放在<html>标签有问题时,它就足够了。(例如,使用JSP模板,其中<head>仅在一个位置定义,但您有多个应用程序。)

模块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模板。这避免了用这种表示逻辑使控制器混乱的需要。控制器需要提供用于通知标题的任何数据,但模板最终决定如何表示它,并且可以像往常一样使用表达式插值和过滤器绑定范围数据。

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

自定义基于事件的解决方案

这里有另一种方法没有被其他方法提到(在撰写本文时)。

你可以像这样使用自定义事件:

// 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。它还允许你设置一个动态标题(如代码示例中所示),这是不可能在路由器的配置对象上使用自定义数据属性的(至少据我所知)。

如果你不能控制标题元素(如asp.net web form),这里有一些东西你可以使用

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