Friday, February 15, 2013

AngularJS & i18next, IE

As I mentioned earlier, to be continued...

And so here I am to fully revoke my earlier rant about Javascript Frameworks.
Since I am working with two that I enjoy at the moment: AngularJS and i18next.

I especially enjoyed them once they were integrated using an i18n directive in Angular (SEE BELOW), so it would automatically handle the data-i18n attribute (with a $watch for locale changes).
And created a few custom Maven plugins/tools to handle creating the i18n JSON data per locale.

My favorite aspect is that I was able to recently submit a defect to i18next and have it fixed within hours.
These are both development communities I'd love to contribute to, if I only had the time.

My least favorite is trying to get AngularJS to work with IE7 or really any IE version. I found a solution from trial/error and reading comments (add ng-app id/class, add json2 for http/resource).
Or rather trying to do anything in IE ever.
Seriously, just for example, printing in IE goes and re-requests resources but only sends session cookies, so printing can mess up when these requests return different responses.
Or how about trying to use a select option with handlebar replacement variables under an Angular ng-switch rendering fine except for in IE.
And back button and history not working in IE7 or compat view.
There are really too many to name, I can't keep track.

Although the worst so far was not being able to upgrade to Angular 1.0.4, although I don't blame Angular (yet) and still assume its something wrong on our app.

But ignoring the minor issues, it's great to have frameworks providing the needed UI functionality and ease of deploy/changes. And still falling back on JQuery when needed.

UPDATE:
I've added some examples for the approach used to combine AngularJS, i18next and JQuery.
I'm sure this will all be outdated quickly, JS libraries are always changing (versions used were roughly AngularJS 1.0.1-1.0.3 and i18next 1.5.10-1.6.0 with a bugfix in 1.6.1pre).
The i18next init was done in the app run, so it would already be setup with the needed options/defaults.

This directive was added to allow AngularJS to process the data-i18n attribute supported by i18next, and avoid manually calling $.i18n. Also catches changes in the rootScope field 'locale', used with $.i18n.setLng, to update the i18n text.

angular.module('appname').directive('i18n', function () {
    return {
        link: function(scope, element, attrs) {
            $(element).i18n();
            scope.$watch('locale', function(newValue, oldValue) {
                if( newValue !== oldValue ) {
                    $(element).i18n();
                }
            }, true);
        }
    }
});

This directive allows handling the i18next data-i18n attribute in HTML such as:

<div data-i18n="page.key"></div>

That could handle 90% of cases. But if you need to have parameters replaced in the text, an app function could be used:

$rootScope.i18n = function(key,options) {
  return $.i18n.t(key,options);
};

This function can be used to replace the parameter {0} in the text (when interpolationPrefix/Suffix are the curly brackets in i18next options):

<div>{{i18n("page.key", {"0": obj.field})}}</div>

1 comment: