Angular i i18next
Widziałem kilka wtyczek i18n dla Angular, ale nie chcę ponownie wymyślać koła. i18next to dobra biblioteka, więc zamierzam go używać.
Stworzyłem dyrektywę i18n, która po prostu wywołuje bibliotekę i18n:
define(['app', 'jquery', 'i18n'], function(app, $, i18n) {'use strict';
app.directive('i18n', function() {
return function($scope, elm, attrs) {
attrs.$observe('i18n', function(value) {
if ($.fn.i18n) {// for some reason, it isn't loaded quickly enough and first directives process fails
$(elm).i18n();
}
});
};
});
});
Na mojej stronie mogę zmienić język w locie:
<a ng-repeat="l in languages"> <img ng-src="images/{{l.id}}.png" title="{{l.label}}" ng-click="setLanguage(l.id)" /> </a>
Teraz mój główny kontroler zdefiniowany w tagu HTML:
define(['app', 'i18n', 'jquery'], function(app, i18n, $) {'use strict';
return app.controller('BuilderController', ['$scope', '$location',
function BuilderController($scope, $location) {
/* Catch url changes */
$scope.$watch(function() {
return $location.path();
}, function() {
$scope.setLanguage(($location.search()).lang || 'en');
});
/* Language */
$scope.languages = [{
id : "en",
label : "English"
}, {
id : "fr",
label : "Français"
}];
$scope.$watch('language', function() {
$location.search('lang', $scope.language);
i18n.init({
resGetPath : 'i18n/__lng__/__ns__.json',
lng : $scope.language,
getAsync : false,
sendMissing : true,
fallbackLng : 'en',
debug : true
});
$(document).i18n();
});
$scope.setLanguage = function(id) {
$scope.language = id;
};
}]);
});
Jak to działa: watcher on language inicjalizuje obiekt i18n z nowymi ustawieniami lokalnymi, a następnie aktualizuje wszystkie DOM używając rozszerzenia i18n jquery. Poza tym specjalnym zdarzeniem moja dyrektywa działa idealnie dla wszystkich innych zadań (szablony używające dyrektywy i18n i renderowane w późniejszym czasie).
Chociaż działa dobrze, wiem, że nie powinienem manipulować DOMem wewnątrz kontrolera, ale ponieważ w końcu nic się nie dzieje, nie znalazłem lepszego rozwiązania.
W idealnej sytuacji chcę, aby Angular ponownie skompilował wszystkie DOM, analizując wszystkie dyrektywy, aby zaktualizować etykiety, ale nie wiem, jak to zrobić. Próbowałem $ scope. $ Apply (): nie działa, ponieważ już w skrócie w tym momencie użyłem wtyczki Scope.onReady bez lepszych wyników.
Oczywiście jestem bardzo nowy w Angular i trudno mi zrozumieć, jak to wszystko działa.