Closed Soviut closed 10 years ago
Hello, thanks for that idea. Currently I'm busy, so I don't have time to implement this. But if you would like to write such a directive, I'll merge it. :) I'll look on this next week again.
Regards, Andre
Here's what I wrote in CoffeeScript for my current project:
app = angular.module 'App'
app.directive 'i18nextCloak', ($rootScope, $i18next, $q) ->
restrict: 'A'
link: (scope, el, attr) ->
defer = $q.defer()
$rootScope.$on 'i18nextLanguageChange', (lng) -> defer.resolve()
defer.promise.then -> el.removeClass 'i18next-cloak'
I use a promise as a sort of "debounce" because the i18nextLanguageChange
event fires more than once. I also went the simplest route and only worried about the class that the directive auto-generates. So my corresponding CSS looks like:
.i18next-cloak {
display: none !important;
}
@archer96 Is there any event that can be used to determine if the digest cycle is complete? the i18nextLanguageChange event can fire before the digest is complete and the i18next keys can sometimes still be visible.
@archer96 From what I can gather from the source, it might be a good idea for the $i18next
provider to keep track of how many directives and filters have been registered. Since providers are singletons, an integer could be incremented each time a directive is linked or a filter is returned. Then just count up as the $i18next function is called and broadcast a completion event.
I use
if($rootScope.$$phase)
to detect if angular is in a digest loop.
Hello,
I'm really sorry that it took so long.
I added an example of how you could do something like i18nextCloak
yourself. Please see:
i18nextLanguageChange
fires when i18next
has loaded (you have to configure ng-i18next
first)
Please let me know if this works for you. I'll close this for now :)
Regards, Andre
Interesting. I actually wound up doing an interval that checks to see if a hidden element has had its text changed. If a simple $timeout
to wait for a digest cycle works then that's way more elegant.
Oh, well, the timeout is just there to show the hide/show progresss. You don't have to do that. :)
Right, but $timeout
forces the code within it to be evaluated on a future digest cycle. So if this works, no actual time would be necessary and the following would work.
$scope.i18nextReady = false;
$scope.$on('i18nextLanguageChange', function () {
if (!$scope.i18nextReady) {
$timeout(function () {
$scope.i18nextReady = true;
}); // no time set
}
});
I'm just want to confirm that the 500 ms isn't just a cheat.
Ah, now I understand what you want :)
What about $apply
or $digest
? (I haven't tested that)
When you reload a page quickly, you can sometimes see the placeholder translation keys before the language file has had a chance to load.
I'd recommend a directive similar to ng-cloak to allow the page, or elements on it, to stay hidden until translations have loaded.