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

当前回答

这里有一种不同的方式来进行标题更改。也许不像工厂函数那样可扩展(可以处理无限的页面),但对我来说更容易理解:

在我的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>

注意到那件斗篷了吗?它与这个答案没有任何关系,但它隐藏了页面,直到加载完成,一个很好的触摸:)这里学习如何: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的生物细节页面。这是从脆皮动物页面使用的部分。[老土,我知道-也许这是一个庆祝各种鸡块的网站;)无论如何,当用户点击任何链接时,你可以更新标题,所以在我的主脆皮动物页面,通往动物细节页面,这是$根。标题更新会这样,就像你在上面的nav.html中看到的那样:

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

其他回答

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

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

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

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

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

对于没有包含标题标签的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/

我刚刚发现了一个很好的方法来设置你的页面标题,如果你使用路由:

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属性代替{{}},这样它们在加载时不会显示

或者,如果你使用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.'
      }
  }