Skip to content
This repository has been archived by the owner on Jan 29, 2024. It is now read-only.

Commit

Permalink
fix(directive): reduced number of watchers by applying translateLangu…
Browse files Browse the repository at this point in the history
…age watcher only when directive is used
  • Loading branch information
cstefanache authored and knalli committed Mar 5, 2016
1 parent 8c5044c commit 961fc92
Show file tree
Hide file tree
Showing 6 changed files with 186 additions and 11 deletions.
126 changes: 126 additions & 0 deletions demo/ex14_translate_language.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<!DOCTYPE html>
<html ng-app='app'>

<head>
<meta charset="utf-8">
<title translate="TITLE">Basic usage</title>
<style>body { text-align: center; }</style>
</head>

<body ng-controller="ctrl">

<!-- An example of changing language in runtime -->
<p>
<a href="#" ng-click="setLang('en_US')">English</a>
|
<a href="#" ng-click="setLang('ru_RU')">Русский</a>
</p>

<!-- Translation by a filter -->
<h1>{{'HEADER' | translate}}</h1>

<!-- Translation by a directive -->
<h2 translate="SUBHEADER">Subheader</h2>

<!-- Using inner HTML as a key for translation -->
<p translate>HTML_KEYS</p>

<hr>

<h4 translate-language="ru_RU">
<p>
<a href="#" ng-click="translateLanguage = 'en_US'">Set local to en_US</a>
<a href="#" ng-click="translateLanguage = 'ru_RU'">Set local to ru_RU</a>
</p>
<!-- Passing a data object to the translation by the filter -->
<p>{{'DATA_TO_FILTER' | translate: tlData}}</p>

<!-- Passing a data object to the translation by the directive -->
<p translate="DATA_TO_DIRECTIVE" translate-values="{{tlData}}"></p>
</h4>

<hr>

<!-- Passing a raw data to the filter -->
<p>{{'RAW_TO_FILTER' | translate:'{ type: "raw" }' }}</p>

<!-- Passing a raw data to the filter -->
<h4 translate="RAW_TO_DIRECTIVE" translate-language="ru_RU" translate-values="{ type: 'directives' }"></h4>

<hr>

<!-- Using a $translate service -->
<p>{{jsTrSimple}}</p>

<!-- Passing a data to the $translate service -->
<p>{{jsTrParams}}</p>

<script src="../bower_components/angular/angular.js"></script>
<script src="../dist/angular-translate.js"></script>

<script>
angular.module('app', ['pascalprecht.translate'])

.config(['$translateProvider', function($translateProvider){

// Adding a translation table for the English language
$translateProvider.translations('en_US', {
"TITLE" : "How to use",
"HEADER" : "You can translate texts by using a filter.",
"SUBHEADER" : "And if you don't like filters, you can use a directive.",
"HTML_KEYS" : "If you don't like an empty elements, you can write a key for the translation as an inner HTML of the directive.",
"DATA_TO_FILTER" : "Your translations might also contain any static ({{staticValue}}) or random ({{randomValue}}) values, which are taken directly from the model.",
"DATA_TO_DIRECTIVE" : "And it's no matter if you use filter or directive: static is still {{staticValue}} and random is still {{randomValue}}.",
"RAW_TO_FILTER" : "In case you want to pass a {{type}} data to the filter, you have only to pass it as a filter parameter.",
"RAW_TO_DIRECTIVE" : "This trick also works for {{type}} with a small mods.",
"SERVICE" : "Of course, you can translate your strings directly in the js code by using a $translate service.",
"SERVICE_PARAMS" : "And you are still able to pass params to the texts. Static = {{staticValue}}, random = {{randomValue}}."
});

// Adding a translation table for the Russian language
$translateProvider.translations('ru_RU', {
"TITLE" : "Как пользоваться",
"HEADER" : "Вы можете переводить тексты при помощи фильтра.",
"SUBHEADER" : "А если Вам не нравятся фильтры, Вы можете воспользоваться директивой.",
"HTML_KEYS" : "Если вам не нравятся пустые элементы, Вы можете записать ключ для перевода в как внутренний HTML директивы.",
"DATA_TO_FILTER" : "Ваши переводы также могут содержать любые статичные ({{staticValue}}) или случайные ({{randomValue}}) значения, которые берутся прямо из модели.",
"DATA_TO_DIRECTIVE" : "И совершенно не важно используете ли Вы фильтр или директиву: статическое значение по прежнему {{staticValue}} и случайное - {{randomValue}}.",
"RAW_TO_FILTER" : "Если вы хотите передать \"сырые\" ({{type}}) данные фильтру, Вам всего лишь нужно передать их фильтру в качестве параметров.",
"RAW_TO_DIRECTIVE" : "Это также работает и для директив ({{type}}) с небольшими модификациями.",
"SERVICE" : "Конечно, Вы можете переводить ваши строки прямо в js коде при помощи сервиса $translate.",
"SERVICE_PARAMS" : "И вы все еще можете передавать параметры в тексты. Статическое значение = {{staticValue}}, случайное = {{randomValue}}."
});

// Tell the module what language to use by default
$translateProvider.preferredLanguage('en_US');

}])

.controller('ctrl', ['$scope', '$translate', function($scope, $translate) {

$scope.tlData = {
staticValue : 42,
randomValue : Math.floor(Math.random() * 1000)
};

$scope.jsTrSimple = $translate.instant('SERVICE');
$scope.jsTrParams = $translate.instant('SERVICE_PARAMS', $scope.tlData);

$scope.setLocalLang = function(langKey) {
$scope.translateLanguage = langKey;
}

$scope.setLang = function(langKey) {
// You can change the language during runtime
$translate.use(langKey);

// A data generated by the script have to be regenerated
$scope.jsTrSimple = $translate.instant('SERVICE');
$scope.jsTrParams = $translate.instant('SERVICE_PARAMS', $scope.tlData);
};

}]);
</script>

</body>
</html>
1 change: 1 addition & 0 deletions demo/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ <h1>Go to demo:</h1>
<li><a href="ex10_translate-cloak.html">How to use translate-cloak</a></li>
<li><a href="ex11_load_partial_files.html">How to load partial files</a></li>
<li><a href="ex13_translate-namespace.htm">How to use translate-namespace</a></li>
<li><a href="ex14_translate_language.htm">How to enforce language on isolated scope</a></li>
</ul>
</body>
</html>
6 changes: 5 additions & 1 deletion src/directive/translate-language.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,17 @@ function translateLanguageDirective() {
scope: true,
compile: function () {
return function linkFn(scope, iElement, iAttrs) {

iAttrs.$observe('translateLanguage', function (newTranslateLanguage) {
scope.translateLanguage = newTranslateLanguage;
});

scope.$watch('translateLanguage', function(){
scope.$broadcast('translateLanguageChanged');
});
};
}
};
}

translateLanguageDirective.displayName = 'translateLanguageDirective';

10 changes: 7 additions & 3 deletions src/directive/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ function translateDirective($translate, $q, $interpolate, $compile, $parse, $roo
// Master update function
var updateTranslations = function () {
for (var key in translationIds) {

if (translationIds.hasOwnProperty(key) && translationIds[key] !== undefined) {
updateTranslation(key, translationIds[key], scope, scope.interpolateParams, scope.defaultText, scope.translateNamespace);
}
Expand Down Expand Up @@ -303,7 +302,9 @@ function translateDirective($translate, $q, $interpolate, $compile, $parse, $roo
if (translateValuesExist || translateValueExist || iAttr.translateDefault) {
scope.$watch('interpolateParams', updateTranslations, true);
}
scope.$watch('translateLanguage', updateTranslations);

// Replaced watcher on translateLanguage with event listener
var unbindTranslateLanguage = scope.$on('translateLanguageChanged', updateTranslations);

// Ensures the text will be refreshed after the current language was changed
// w/ $translate.use(...)
Expand All @@ -321,7 +322,10 @@ function translateDirective($translate, $q, $interpolate, $compile, $parse, $roo
observeElementTranslation(iAttr.translate);
}
updateTranslations();
scope.$on('$destroy', unbind);
scope.$on('$destroy', function(){
unbindTranslateLanguage();
unbind();
});
};
}
};
Expand Down
1 change: 0 additions & 1 deletion src/filter/translate.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ function translateFilterFactory($parse, $translate) {
'use strict';

var translateFilter = function (translationId, interpolateParams, interpolation, forceLanguage) {

if (!angular.isObject(interpolateParams)) {
interpolateParams = $parse(interpolateParams)(this);
}
Expand Down
53 changes: 47 additions & 6 deletions test/unit/directive/translate-language.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,23 @@ describe('pascalprecht.translate', function () {

var element;

beforeEach(module('pascalprecht.translate'));
beforeEach(module('pascalprecht.translate', function ($translateProvider) {
$translateProvider
.translations('en', {
'message': 'Hello'
})
.translations('de', {
'message': 'Hallo'
})
.preferredLanguage('en');
}));

var $compile, $rootScope;
var $compile, $rootScope, $translate;

beforeEach(inject(function (_$compile_, _$rootScope_) {
beforeEach(inject(function (_$compile_, _$rootScope_, _$translate_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
$translate = _$translate_;
}));

it('should add translateLanguage to current scope', function () {
Expand All @@ -24,10 +34,41 @@ describe('pascalprecht.translate', function () {
});

it('should not change parent scope language', function () {
$rootScope.translateLanguage = 'he';
element = $compile('<div translate-language="en"></div>')($rootScope);
$rootScope.translateLanguage = 'de';
element = $compile('<div translate translate-language="en">message</div>')($rootScope);
$rootScope.$digest();
expect($rootScope.translateLanguage).toBe('de');

expect(element.html()).toBe('Hello');
});

it('should be possible to change at runtime', function () {
element = $compile('<div translate translate-language="en">message</div>')($rootScope);
$rootScope.$digest();

$rootScope.$$childTail.translateLanguage = 'de';
$rootScope.$digest();

expect(element.html()).toBe('Hallo');
});

it('should not be changed by parent scope language', function() {
var element = angular.element('<span><p translate>message</p></span>');
var isolatedElement = angular.element('<h5 translate-language="en" translate>message</h5>');

$compile(element)($rootScope);
$compile(isolatedElement)($rootScope.$new(true, $rootScope));

element.append(isolatedElement);
$rootScope.$digest();

expect(element.find('p').html()).toBe('Hello');
expect(isolatedElement.html()).toBe('Hello');
$translate.use('de');
$rootScope.$digest();
expect($rootScope.translateLanguage).toBe('he');

expect(element.find('p').html()).toBe('Hallo');
expect(isolatedElement.html()).toBe('Hello');
});
});
});

0 comments on commit 961fc92

Please sign in to comment.