Как динамически менять тег заголовка 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>