New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

One-way binding in combination with staticFilesLoader not working #967

Closed
filidorwiese opened this Issue Mar 20, 2015 · 9 comments

Comments

Projects
None yet
5 participants
@filidorwiese

filidorwiese commented Mar 20, 2015

When using Angular 1.3 one-way binding on a translate filter, one can deregister a watch after it's value has successfully been translated. With ng-translate this already works out of the box, for example:

{{ ::'TRANSLATION_ID' | translate }}

(Plunkr: http://plnkr.co/edit/PJwaX6pdKvriU3aaCMCl)

But it only works if the translations where synchronously loaded. When using an asynchronous loader like, staticFilesLoader, the above example renders as:

TRANSLATION_ID

(Plunkr: http://plnkr.co/edit/jYs6zS23ejC6eqULLaH2)

Is this a known issue and is there a workaround?

Ps. I appreciate that staticFilesLoader is usually only used in situations where you'd also need runtime language switching. In our situation this is not the case, switching a language is done per hard-refresh because also other data (like pricing) has to be re-fetched. And since a user usually switches a language only once, it's fine for us to use a hard-refresh in combination with one-time bindings to keep the angular watch down low. We can't however embed the language json as a script tag since we don't want the index to be dynamically generated.

@knalli

This comment has been minimized.

Member

knalli commented Mar 20, 2015

When using Angular 1.3 one-way binding on a translate filter, one can deregister a watch after it's value has successfully been translated.

That's actually wrong. It will not be registered after a successful translation but any filter output. The AngularJS one-time-binding simply does not know about the internal state of value. Even a "TRANSLATION_ID" is a valid response.

Unless we can skip/stop the filter, this will not work for asynchronous data (read: filter created before translations are loaded finally).

@filidorwiese

This comment has been minimized.

filidorwiese commented Mar 20, 2015

I understand, so there is no workaround to use the one-way binding syntax with the ng-translate filter if asynchronous loading is involved. Does using the translate directive offer improved performance for large-scale apps that use hundreds of translatable strings throughout the views? Or is the overhead of compiling hundreds of directives more then it could save?

@knalli

This comment has been minimized.

Member

knalli commented Mar 20, 2015

Components like dialogs which are rendered on demand only without language change actions, you can use this. Also the filter will bypass any currently running loaders (i.e. XHR), because a filter cannot be "blocked".

So yes, there is no other way.

Regarding the performance: We have a larger app with several translation and do not notice such issues.

@filidorwiese

This comment has been minimized.

filidorwiese commented Mar 20, 2015

Thanks for your replies :)

To me it's feels wrong to not use one-time bindings on the hundreds of strings that I know won't change after successful translation. I do admit that in our current code-base I haven't experience performance issues either, however I've noticed that the watch count is going upwards rapidly and I want to plan ahead to avoid having to re-factor the entire code base later on after we've added more and more translations. Especially since we have a strong mobile user base that we need to support.

Using the translate directive looks to be the answer since it only updates the translations when needed instead of during every digest loop, it definitely decreases the watchers count.

@knalli knalli closed this Mar 26, 2015

@ajwhite

This comment has been minimized.

ajwhite commented Mar 30, 2015

I've been using a custom directive that extends upon angular-translate

https://github.com/ajwhite/angular-translate-once

@shaderzak

This comment has been minimized.

shaderzak commented Dec 23, 2015

@filidorwiese So I tried some ugly workaround. This works for me, but now AJAX for synchronous is depreciated and some years later it will not work. Hope it will help you somehow.

angular.module('app.services', ['ngSanitize', 'pascalprecht.translate'])
.config(['$translateProvider',  function($translateProvider) {
        var language = 'en';
        $translateProvider.preferredLanguage(language);
        $translateProvider.fallbackLanguage(language);  
        $.ajax({
            dataType: "json",
            url: "languages/" + language + ".json",
            data: {},
            async: false,
            success: function (data) {
                $translateProvider.translations(language, data);
            }
        });
    }
]);
@mkoczorowski

This comment has been minimized.

mkoczorowski commented Jan 26, 2016

Why this is closed? is there a solution ?

@knalli

This comment has been minimized.

Member

knalli commented Jan 26, 2016

There is no "solution". You can use one-way-filter only if you have the data being available at the first time. An asynchronous loading process cannot make this.

@mkoczorowski

This comment has been minimized.

mkoczorowski commented Jan 26, 2016

ok thanks. I will look into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment