如何在Angular中使用$routeProvider更改页面标题

13

我发现了几个类似的问题,但是没有一个答案对我有帮助。它们都涉及某种类型的 $location 依赖项,而我无法正确注入。

以下是我的代码:

(function() {

    // App dependencies
    var app = angular.module('portalExchange',
                        ['ngRoute',
                         'app-products',
                         'app-manage',
                         'app-profile']);

    // [ Main Controller ] : PortalController
    app.controller('PortalController', function($scope) {
        if ($('.top_link_dashboard').hasClass('unactive_top')) {
            $('.top_link_dashboard').removeClass('unactive_top');
            $('.top_link_dashboard').addClass('active_top');
        }
    });

    // Controller for Dashboard
    app.controller('DashboardController', function() {
    });

    // Controller for Developers
    app.controller('DevelopersController', function($scope) {
        // Page.setTitle('Developers');
    });

    // Controller for Quote
    app.controller('QuoteController', function($scope) {
        // Page.setTitle('Begin Quote');
    });

    // Directive for Header
    app.directive('appHeader', function () {
        // Type of Directive, E for element, A for Attribute
        // url of a template
        return {
            restrict: 'E',
            templateUrl: 'templates/modules/globals/app-header.html'
        };
    });

    // Directive for Footer
    app.directive('appFooter', function () {
        return {
            restrict: 'E',
            templateUrl: 'templates/modules/globals/app-footer.html',
            controller: function(){
                this.date = Date.now();
            },
            controllerAs:'footer'
        };
    });

    // configure our routes
    app.config(function($routeProvider) {
        $routeProvider

        // route for the dashboard page
        .when('/', {
            templateUrl : 'templates/sections/app-dashboard.html',
            controller  : 'DashboardController'
        })

        // route for the dashboard page
        .when('/dashboard', {
            title : 'My Dashboard',
            templateUrl : 'templates/sections/app-dashboard.html',
            controller  : 'DashboardController'
        })

        // route : Developers Page
        .when('/developers', {
            title : 'For Developers',
            templateUrl : 'templates/sections/app-developers.html',
            controller  : 'DevelopersController'
        })

        // route : Begin Quote
        .when('/quote', {
            title : 'Begin Quote',
            templateUrl : 'templates/sections/app-quote.html',
            controller  : 'QuoteController'
        });
    });

    app.run(['$rootScope', '$route', function($rootScope) {
        $rootScope.$on('$routeChangeSuccess', function(newVal, oldVal) {
            if (oldVal !== newVal) {
                document.title = $route.current.title;
            }
        });
    }]);

})();

RUN函数

app.run(['$rootScope', '$route', function($rootScope) {
    $rootScope.$on('$routeChangeSuccess', function(newVal, oldVal) {
        if (oldVal !== newVal) {
            document.title = $route.current.title;
        }
    });
}]);
HTML
<!DOCTYPE html>
<html lang="en" ng-app="portalExchange" ng-controller="PortalController as portal">
<head>
    <meta charset="utf-8">
    <title ng-bind="title">myApp</title>
</head>

控制台显示了什么错误? - Acsisr
每次位置改变,为什么不直接调用 document.title = $scope.myTitle - Mike Driver
2
@Mike 没错,不需要再绑定一个观察者。 - dfsq
3个回答

48

我做的方法非常简单。在路由配置中定义title

.when('/dashboard', {
    title : 'My Dashboard',
    templateUrl : 'templates/sections/app-dashboard.html',
    controller  : 'DashboardController'
})

你需要监听$routeChangeSuccess事件,然后简单地设置document.title。在应用程序的运行块中执行此操作(这是最好的位置):

那么您需要监听$routeChangeSuccess事件,并在应用程序运行块(最佳位置)中仅设置document.title

app.run(['$rootScope', '$route', function($rootScope, $route) {
    $rootScope.$on('$routeChangeSuccess', function() {
        document.title = $route.current.title;
    });
}]);

这种方法的好处是可以避免使用一个额外的绑定ng-bind="title",这很好。


抱歉,我仍然遇到麻烦:( $root未定义,我不确定我是否正确注入它...出现了多个错误。我正在上传我的最新代码,并很快会发布链接。 - Leon Gaban
抱歉,当然您还需要注入$route服务。请查看更新后的答案。 - dfsq
1
你需要在run函数中注入$rootScope$route服务,就像我在答案中的例子一样。 - dfsq
1
@dfsq $routeChangeSuccess 的签名是 (event, currentRoute, previousRoute),所以你的检查 (oldValue !== newVal) 是不是多余的,或者我漏掉了什么?也许在你的函数闭包中收集所有三个参数,然后检查 (currentRoute !== previousRoute),但即使这样似乎也有点多余,因为我们已经在 routeChangeSuccess 中了。 - lukkea
但是,简洁的解决方案加1分! - lukkea
@lukkea 很好的发现,确实 (oldValue !== newVal) 是多余的,因为它永远不会是 false - dfsq

4

这是另一种方式

app.run(['$rootScope', function($rootScope) {
    $rootScope.$on('$routeChangeSuccess', function(_, current) {
        document.title = current.$$route.title;
    });
}]);

有时候$route注入会导致问题(例如,在运行单元测试时)。


2

以下内容与主题有些偏离,但我尝试在一个使用ui-router的Angular应用中管理页面标题时遇到了一些问题。首先,当然必须将route$routeChangeSuccess更改为$state$stateChangeSuccess。其次,我发现页面标题在浏览器能够将前一页标题添加到历史记录之前就已经被更新了,因此我不得不向事件处理程序添加一个timeout,代码如下:

angular.module('myApp').run(appRunFunction);

appRunFunction.$inject = ['$rootScope', '$state', '$timeout'];

function appRunFunction($rootScope, $state, $timeout) {
    $rootScope.$on('$stateChangeSuccess', function() {
        $timeout(function() { document.title = $state.current.title; }, 100);
    });
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接