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

当前回答

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

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

其他回答

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

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。您必须下载压缩文件并在本地运行,才能看到标题的变化。

这是一个适合我的解决方案,它不需要注入$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);
}

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

$window.document.title = someTitleYouCreated;

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

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

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

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