Saltar al contenido

Uso correcto de la traducción angular en controladores

Bienvenido a proyecto online, en este lugar hallarás la resolución a lo que estás buscando.

Solución:

Recomendado: no traduzca en el controlador, traduzca en su vista

Recomendaría mantener su controlador libre de lógica de traducción y traducir sus cadenas directamente dentro de su vista de esta manera:

'TITLE.HELLO_WORLD'

Usando el servicio provisto

Angular Translate proporciona la $translate servicio que puede utilizar en sus controladores.

Un ejemplo de uso del $translate el servicio puede ser:

.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) 
    $translate('PAGE.TITLE')
        .then(function (translatedValue) 
            $scope.pageTitle = translatedValue;
        );
);

El servicio de traducción también tiene un método para traducir cadenas directamente sin la necesidad de manejar una promesa, usando $translate.instant():

.controller('TranslateMe', ['$scope', '$translate', function ($scope, $translate) 
    $scope.pageTitle = $translate.instant('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
);

La desventaja de usar $translate.instant() podría ser que el archivo de idioma aún no se haya cargado si lo está cargando de forma asíncrona.

Usando el filtro provisto

Esta es mi forma preferida, ya que no tengo que manejar las promesas de esta forma. La salida del filtro se puede establecer directamente en una variable de alcance.

.controller('TranslateMe', ['$scope', '$filter', function ($scope, $filter) 
    var $translate = $filter('translate');

    $scope.pageTitle = $translate('TITLE.DASHBOARD'); // Assuming TITLE.DASHBOARD is defined
);

Usando la directiva proporcionada

Dado que @PascalPrecht es el creador de esta increíble biblioteca, recomendaría seguir su consejo (ver su respuesta a continuación) y usar la directiva provista que parece manejar las traducciones de manera muy inteligente.

La directiva se encarga de la ejecución asincrónica y también es lo suficientemente inteligente como para dejar de ver los identificadores de traducción en el alcance si la traducción no tiene valores dinámicos.

En realidad, debería utilizar la directiva translate para este tipo de cosas.

La directiva se encarga de la ejecución asincrónica y también es lo suficientemente inteligente como para dejar de ver los identificadores de traducción en el alcance si la traducción no tiene valores dinámicos.

Sin embargo, si no hay forma de evitarlo y realmente tengo que usar $translate servicio en el controlador, debe envolver la llamada en un $translateChangeSuccess evento usando $rootScope en combinación con $translate.instant() como esto:

.controller('foo', function ($rootScope, $scope, $translate) 
  $rootScope.$on('$translateChangeSuccess', function () 
    $scope.pageTitle = $translate.instant('PAGE.TITLE');
  );
)

Entonces por qué $rootScope y no $scope? La razón de esto es que en los eventos de angular-translate son $emited en $rootScope en vez de $broadcasted en $scope porque no necesitamos transmitir a través de toda la jerarquía de alcance.

Por qué $translate.instant() y no solo asincrónico $translate()? Cuándo $translateChangeSuccess se activa el evento, es seguro que los datos de traducción necesarios están allí y no se está produciendo una ejecución asincrónica (por ejemplo, ejecución de cargador asincrónico), por lo tanto, podemos usar $translate.instant() que es sincrónico y solo asume que hay traducciones disponibles.

Desde la versión 2.8.0 también hay $translate.onReady(), que devuelve una promesa que se resuelve tan pronto como las traducciones están listas. Ver el registro de cambios.

EDITAR: Consulte la respuesta de PascalPrecht (el autor de angular-translate) para una mejor solución.


La naturaleza asincrónica de la carga causa el problema. Ya ves, con translate , Angular observará la expresión; cuando se cargan los datos de localización, el valor de la expresión cambia y la pantalla se actualiza.

Entonces, puedes hacerlo tú mismo:

.controller('FirstPageCtrl', ['$scope', '$filter', function ($scope, $filter) 
    $scope.$watch(
        function()  return $filter('translate')('HELLO_WORLD'); ,
        function(newval)  $scope.pageTitle = newval; 
    );
);

Sin embargo, esto ejecutará la expresión observada en cada ciclo de resumen. Esto es subóptimo y puede o no causar una degradación visible del rendimiento. De todos modos, es lo que hace Angular, por lo que no puede ser tan malo …

Recuerda algo, que tienes la capacidad de explicar si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *