如何动态更改html标题标记并将其翻译为AngularJS中的语言

时间:2015-02-27 08:52:27

标签: angularjs

我有一个AngularJS Web应用程序。我想以恐怖的方式更改页面标题。我希望将配置的语言考虑在内,因此标题应以不同的语言显示。

当我导航到不同的页面时,我成功地改变了标题。我得到了这篇文章How to dynamically change header based on AngularJS partial view?的第三种方法,对我来说看起来最简单(我的意思是使用$ rootScope的方法)。

我只是一个问题。当我在页面上时,让我们说索引,假设语言配置是英语,标题用英语正确显示。但是如果我改变语言,例如改为西班牙语(在导航栏的下拉列表中),标题不会改变。如果我导航到另一个页面,标题将以西班牙语正确显示。

请找相关代码:

HTML:

<title ng-bind="title"></title>

每个控制器:

.controller('HomeCtrl', function HomeCtrl($scope, $rootScope, $translate) {

        $rootScope.title = $translate('PAGE_TITLE_INDEX');
        ...
}


.controller ('AboutCtrl', function ($scope, $rootScope, $translate) {               

        $rootScope.title = $translate('PAGE_TITLE_ABOUT');
        ...
}

LANGUAGE SELECT DROPDOWN

<div ng-controller="LocationCtrl" style="padding-top: 5px">
            <select class="bootstrap-select-language show-tick" 
                    ng-change="changeLanguage(langKey)" 
                    ng-model="langKey" 
                    data-header="Choose your language..." 
                    ng-options="language.locale as language.name for language in translationLanguages"                  
                    bs-select
                    data-width="150px">                                  
            </select>           
        </div>

控制器中的翻译功能

$scope.changeLanguage = function (langKey) {
            $scope.langKey = langKey;
            $translate.uses(langKey);
            ...
}

更新

我认为对于这种情况,上面帖子中的第一种方法是正确的(我的意思是,将标题保留在服务中并从控制器获取和设置)。这样,您可以在翻译控制器中获取当前标题值并以动态方式更改它。正确?

2 个答案:

答案 0 :(得分:3)

我们一直在努力解决许多潜在的解决方案。我们正在使用Ionic,angular-translate,嵌套选项卡,并试图在一个页面上更改语言 - 它正在将已翻译的视图标题推送到导航栏上。所以我们删除了所有的视图标题,$ scope。$ emits,并将其减少到最低限度(在处理错误导致代码减少的情况下,这种情况很少见):

首先,您可以将ng-bind和angular-translate语句混合使用 - 只要使用$ translate.use(lang)更改语言,这些语句就会更新:

<html ng-app="myApp">
  <head>
    <title ng-bind="('SITE_TITLE' | translate) + ((pageTitle) ? ' - ' + (pageTitle | translate) : '')"></title>
    ....

在定义状态时,将数据组件中的pageTitle设置为适当的翻译键 - 对所有非抽象状态执行此操作,如果您希望页面仅显示SITE_TITLE,请将其保留为未定义:

  $stateProvider
    .state('tab.account', {
      url: '/account',
      views: {
        'tab-account': {
          templateUrl: 'app/account/tab-account.html',
          controller: 'AccountCtrl',
          controllerAs: 'account'
        }
      },
      data: {
        requireLogin: true,
        pageTitle: 'ACCOUNT_TAB_TITLE',
      }
    });

在app.js配置中,注入$ rootScope并在$ stateChangeStart事件监听器(或$ stateChangeSuccess)中设置$ rootScope.pageTitle:

  $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    if (toState.data.pageTitle) {
      $rootScope.pageTitle = toState.data.pageTitle;
    }
  });

并且,如果使用Ionic,则从模板中移除所有视图标题(在我们的示例中,我们使用Ionic)并在“离子视图”中设置“view-title”意味着当您使用选项更改语言时选择我们的帐户页面,视图标题被错误地应用于导航标题...以下从州获取data.pageTitle并且比我们的更清洁,并允许我们设置导航栏的页面 - 标题不同:

<ion-view>
  <ion-nav-title>{{pageTitle | translate}}</ion-nav-title>

答案 1 :(得分:2)

你使用的方法应该没问题。 <title>未更改,因为$translate.uses(langKey);不会更改$rootScope上的任何内容。你可以试试这个:

// i.e. for the HomeCtrl
$scope.changeLanguage = function (langKey) {
    $scope.langKey = langKey;
    $translate.uses(langKey);
    $rootScope.title = $translate('PAGE_TITLE_INDEX');
}

UPDATE :如果你不想在每个控制器中都有这个功能,我认为你当前代码库最简单的方法是:

angular.module('your-module')
.run(function($rootScope, $translate) {
    // serves as a cache
    var currentTitleKey = '';

    $rootScope.$on('changeTitle', function(e, titleKey) {
        // update if parameter is defined, else reuse
        currentTitleKey = (titleKey || currentTitleKey);

        $rootScope.title = $translate(currentTitleKey);
    });
});

您的页面控制器(即HomeCtrl)将成为:

// doesn't need $rootScope
$scope.$emit('changeTitle', 'PAGE_TITLE_INDEX');

LocationCtrl只会:

$scope.changeLanguage = function (langKey) {
    $scope.langKey = langKey;
    $translate.uses(langKey);
    // refresh current title
    $scope.$emit('changeTitle');
}