问题
If i eg. use a select drop down input field in my header (more precisely in my sitewide nav-bar which is custom element), and have that value set globally in a shared state object. If I - on languageChanged(value)
(inside the nav-bar custom element) also change the this.i18n.setLocale('de-DE')
How would I then refresh the i18n translated string interpolated values (eg. ${'status_deceased' | t}
) inside my templates without having to navigate to a new route and back as I do right now?
I found this issue on github about the problem https://github.com/aurelia/i18n/issues/6 but since I need this to work, I'm hoping that some clever workaround exists, except from having to use window.location to reload the page :/
Edit
If I'm understanding this correctly it seems it might just be my lucky day, and such a feature has just been added 8 days ago, although still undocumented: https://github.com/aurelia/templating-resources/pull/126 - Can anyone figure out and tell me how to implement this, using this new feature perhaps? If I figure this out myself, I'll update this thread with the solution :-)
回答1:
When the next release goes out you'll be able to assign a "signal name" to a binding using the signal
binding behavior like this:
<h1>${'title_key' | t & signal:'i18n'}</h1>
<p>${'content_key' | t & signal:'i18n'}</p>
The &
symbol denotes a "Binding Behavior" (as opposed to |
for value-converters). Binding behaviors are resources that add "behavior" to a binding. They have full access to the binding instance and are notified prior to the binding's bind
and unbind
lifecycle events.
Aurelia will ship with several built-in binding behaviors: "throttle", "debounce", "one-time", "signal" etc. You also have the option of creating your own binding behaviors.
In the example above we've given the title
and content
interpolation bindings a "signal" name of "i18n". The name is arbitrary, we just need to know what it is so we can "signal" the bindings to refresh using the BindingSignaler
like this:
import {BindingSignaler} from 'aurelia-templating-resources';
import {inject} from 'aurelia-framework';
@inject(BindingSignaler)
export class App {
constructor(signaler) {
this.signaler = signaler;
}
// invoking this method will refresh all bindings in the application
// with the "signal name" of "i18n"
refreshBindings() {
this.signaler.signal('i18n');
}
}
I imagine once the binding behavior feature drops there will be additional work in the i18n plugin to combine the t
value converter with some version of the signal
binding behavior to enable terse binding expressions that take care of both translation and refreshing the bindings when the language changes so you might want to sit tight for the time being.
EDIT If you need something today you could take advantage of an existing Aurelia feature: bindings are re-evaluated when converter parameters change.
- Create a new class:
export class LanguageChangedNotifier {
signal = 0;
notify() {
this.signal++;
}
}
- inject this class into all view-models and add the instance as a property:
@inject(LanguageChangedNotifier)
export class App {
constructor(notifier) {
this.notifier = notifier;
}
}
- Use the notifier in your
t
bindings (it won't impact the behavior of thet
value converter):
${'status_deceased' | t:notifier.signal}
- When you change the locale, use the notifier to refresh the bindings:
this.notifier.notify();
来源:https://stackoverflow.com/questions/33489609/refreshing-i18n-translated-string-interpolated-values-in-aurelia