Как динамически менять тег заголовка html и переводить на языки в AngularJS

У меня есть веб-приложение AngularJS. Я хотел бы изменить название страницы динамически. Я бы хотел, чтобы язык был настроен с учетом, поэтому заголовок должен отображаться на разных языках.

Мне удалось изменить название динамически, когда я перехожу на разные страницы. Я получил третий подход к этому сообщению Как динамически изменить заголовок на основе частичного просмотра AngularJS?, который выглядел наиболее простым для меня (я имею в виду тот, у кого используется $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');
        ...
}

ЯЗЫК ВЫБРАТЬ 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);
            ...
}

UPDATE

Я думаю, что для этого сценария первый подход в вышеупомянутой статье является правильным (я имею в виду, сохраняя заголовок в сервисе и получая и устанавливая его с контроллеров). Таким образом, вы можете получить текущее значение названия в контроллере переводов и изменить его динамически. Правильно?

Ответ 1

Подход, который вы использовали, должен быть в порядке. <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');
}

ОБНОВЛЕНИЕ. Если вы не хотите иметь функцию в каждом контроллере, я думаю, что самый простой способ с вашей текущей базой кода:

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

Ответ 2

Мы боролись за многие потенциальные решения. Мы используем 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 в компоненте данных соответствующий ключ перевода - сделайте это для всех не абстрактных состояний, оставьте его undefined, если вы хотите, чтобы страница отображала только 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 и установите $rootScope.pageTitle в слушателе событий $stateChangeStart (или $stateChangeSuccess):

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

и, если вы используете Ionic, удалите все заголовки просмотров из шаблонов (в нашем случае мы используем Ionic), а установка "view-title" в "ion-view" означает, что при смене языка с использованием опции выберите наша страница учетной записи, название-представление было неправильно применено к титулу nav-title... Следующее забирает data.pageTitle из состояния и намного чище, чем у нас, и позволяет использовать страницы, на которых мы устанавливаем nav-bar- название по-разному:

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