Skip to content
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

Issue when changing language #47

Closed
FabienDehopre opened this issue Jan 11, 2017 · 16 comments
Closed

Issue when changing language #47

FabienDehopre opened this issue Jan 11, 2017 · 16 comments
Labels

Comments

@FabienDehopre
Copy link
Contributor

I have an application with many modules (some lazy-loaded) and a ton of components..
When the user change the language of the application using a menu, not all the translation are updated.
For the translations I use a mix of pipe and directive depending on where I need to put the texts.
All my components extend the Locale class as described in the documentation.
At first glance, it seems that the texts translated using the pipe are the only texts affected by the issue. And I think that the issue appears only on components with the OnPush change detection strategy.

So, for the moment, my work around for this issue is to force a reload of the whole application using location.reload().

Here is a link to a video showing the issue: https://drive.google.com/open?id=0B0duWwBStbRAemI1V1lPaXlkYTA

@robisim74
Copy link
Owner

I don't know why you are using OnPush change detection strategy, but it's normal that the pure pipes don't work if you use it, because the input parameter (lang) is updated by an event when the http request is completed.

@FabienDehopre
Copy link
Contributor Author

It seems odd to me because I use other pure pipe in my components with OnPush change detection strategy and I don't have any issue.
In the first place, I use the OnPush change detection strategy for performance reason. I have long list of bound items.
Also, I use @ngrx/store for my state management.. so I might store the current language and locale in my store and subscribe to your observables/events to update the central application store. Or temporarily disable onpush on my components

@robisim74
Copy link
Owner

I may have found a solution: because the input parameter is updated by a subscription, I can add the calling to the markForCheck API in the Locale class in this way:

    constructor(public locale?: LocaleService, public localization?: LocalizationService, public changeDetectorRef?: ChangeDetectorRef) {

        if (this.localization != null) {

            this.lang = this.localization.languageCode;

            // When the language changes, subscribes to the event & updates lang property.
            this.localization.translationChanged.subscribe(

                // Generator or next.
                (language: string) => {
                    this.lang = language;
                    if (this.changeDetectorRef) { this.changeDetectorRef.markForCheck() }; // OnPush Change Detection strategy.
                }

            );

        }
...

But then you have to pass a new parameter to the Locale superclass when you use in the component changeDetection: ChangeDetectionStrategy.OnPush:

constructor(public locale: LocaleService, public localization: LocalizationService, public cd: ChangeDetectorRef) {
        super(locale, localization, cd);

What do you think?

@FabienDehopre
Copy link
Contributor Author

I think it's a good idea.
It's not a big deal to pass one more argument to the base class.
I already have base classes for my services with more than 3 arguments in the super constructor.

@robisim74
Copy link
Owner

I made the commit that adds support for OnPush Change Detection strategy.

You should remove the library from your npm modules, and follow the instructions in the README to build & install the library locally.

Please, try it in your app, and let me know if it works fine, so I'll include this support in the next release.

P.S. Just to explain: because the input parameter of the pure pipes changes when the http request is completed (ie after the event has been generated), markForCheck method generates an event that allows the OnPush strategy to update the value. More explanation here: https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html

@FabienDehopre
Copy link
Contributor Author

ok. I will test your change monday morning.
I'll keep you posted.

@skyfremen
Copy link

Understand that pure pipes don't work, because the input parameter (lang) is updated by an event when the http request is completed.

How should I reflect the changes of the pure pipes using locale.setCurrentLocale();?
I am not using OnPush change detection strategy*

@FabienDehopre
Copy link
Contributor Author

@robisim74 Your change is working fine :-)
You can include this change in the next release.

@robisim74
Copy link
Owner

@FabienDehopre Thanks for reporting. I'll update you when I'll release the new version

@robisim74
Copy link
Owner

@skyfremen You have to extend the Locale superclass in your components: it provides the subscriptions to update the parameters. If you have problems, please open a new issue

@FabienDehopre
Copy link
Contributor Author

any idea when you will release this change ?

@robisim74
Copy link
Owner

Tonight I'll release the new minor version. In a few days the new major version. Both will have this features.

@robisim74
Copy link
Owner

New minor version is out.

@robisim74
Copy link
Owner

@FabienDehopre I'm closing this issue. If you need, open a new issue. Greetings

@macwier
Copy link

macwier commented Sep 25, 2018

@robisim74

Hi, just a question: Would it be possible to get the same behaviour by using both the @Language decorator and @input on the lang: string property?

@robisim74
Copy link
Owner

Hi @MaciejWierzchowski, did you try it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants