atticoos / angular-translate-once

:currency_exchange: Extension of angular-translate for one time bindings
53 stars 11 forks source link

[question] adding tooltip attribute #1

Closed garfield69 closed 9 years ago

garfield69 commented 9 years ago

I was hoping that I could do a translate-once over the tooltip attribute. So I added tooltip to the ATTRS

ATTRS = ['value', 'title', 'alt', 'placeholder', 'tooltip'],

but even though the translations takes place <i class="glyphicon glyphicon-chevron-down" ng-click="setView('date')" translate-once-tooltip="DATEPICKER/calendar-monthview/glyph/tooltip" tooltip="switch to Month view"></i> the tooltip text does not get displayed on the view :-(

I was wondering if you have any insight as to why this does not work?

atticoos commented 9 years ago

are you using an external library for the tooltip?

garfield69 commented 9 years ago

I am using ui-bootstrap from the angularUI team. ui-bootstrap-tpls-0.13.0.min.js to be exact.

atticoos commented 9 years ago

This might be a bit of a race condition, I'll need to look a little further at how their integration works.

The problem is likely that the tooltip attribute becomes assigned after the ui-bootstrap integrates with the directive. So it goes through this process:

You might be able to get around this by starting the element off with a tooltip="x" attribute, and then ui-bootstrap would detect that when it enters context. Afterwards, the translate-once-tooltip would resolve and update the existing tooltip attribute, and inherently ui-bootstrap will be using the new translation that was assigned to it.

Give that a shot by simply having the element start off with a tooltip="X" value, and see if it ends up working. If that's the case, we may want part of the translate-once-X phase initialize the attribute for any other directives that might want to use it.

garfield69 commented 9 years ago

interesting result. so to begin with, this is the source code; I have placed the tooltip="X" at the start of the icon element.

<h2>{{date|date:"MMMM yyyy"}} <i tooltip="X" class="glyphicon glyphicon-chevron-down" ng-click="setView('date')" translate-once-tooltip="DATEPICKER/calendar-monthview/glyph/tooltip"></i>
</h2>

and this is what came out. Looks like ui-boostrap has invoked a tooltip-popup overlay? image ui-bootstrap is getting too clever for me.

atticoos commented 9 years ago

This might lead you in the right direction https://github.com/angular-ui/bootstrap/blob/master/src/tooltip/tooltip.js#L287

Which sounds like it only observes changes if that attribute, useContentExp is true.

Looking deeper, the directive, tooltip, is defined here

However, tooltipTemplate is defined here

Notice how tooltipTemplate goes ahead and passes useContentExp: true to the constructor, where tooltip does not.. I think that's your solution.

Try setting this up to use translate-once-tooltip-template -- where it'll end up setting tooltip-template as the attribute which should register changes.

It's such a weird implementation.. here is where the determination is made whether to use a @ binding of the value from tooltip (which does not evaluate changes), or if useContentExp is set, then it goes ahead and uses the dynamic binding and registers changes. What a mess.

GL HF

garfield69 commented 9 years ago

Thank you for the tip. Ended up implementing it as below, which seems to work fine now. source:

<h2>{{date|date:"MMMM yyyy"}} <i tooltip-template="'calendarMonthView.html'" class="glyphicon glyphicon-chevron-down" ng-click="setView('date')"></i>
</h2>
[...]
<script type="text/ng-template" id="calendarMonthView.html">
  <span translate-once="DATEPICKER/calendar-monthview/glyph/tooltip"></span>
</script>

result" image

atticoos commented 9 years ago

Glad you brought it up, it introduces an interesting problem where other directives may require the attribute being set. Going to think about this one.

Glad you got it working, your solution makes sense. Unfortunate that you have to create a template solely for the tooltip though :(

garfield69 commented 9 years ago

Yes. From a performance point of view, I suspect it will be more efficient to just leave the existing tooltip code alone, rather than pipe it through a dedicated template in order to get the benefit of a translate once hit, for what is in the end, just a plain text label. I'll run it past the project author and go with what ever he decides. Thanks again for your valuable input.


From: Atticus White [mailto:notifications@github.com] Sent: Saturday, 06 June 2015 09:19 To: ajwhite/angular-translate-once Cc: garfield69 Subject: Re: [angular-translate-once] [question] adding tooltip attribute (#1)

Glad you brought it up, it introduces an interesting problem where other directives may require the attribute being set. Going to think about this one.

Glad you got it working, your solution makes sense. Unfortunate that you have to create a template solely for the tooltip though :(

Reply to this email directly or view https://github.com/ajwhite/angular-translate-once/issues/1#issuecomment-109 443805 it on GitHub. https://github.com/notifications/beacon/AGnK-HmsyIcdSle3gAdoivpGAe6q4GiRks5 oQgnagaJpZM4E5Zwz.gif


This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

atticoos commented 9 years ago

I suspect it will be more efficient to just leave the existing tooltip code alone, rather than pipe it through a dedicated template in order to get the benefit of a translate once hit, for what is in the end, just a plain text label.

Yeah might as well just do a normal translation filter tooltip="{{'KEY' | translate }}"

And if you don't asynchronously load your translation files, you might be able to get away with a regular one-time binding, {{:: 'KEY' | translate }}, if you're on Angular 1.3

Even if you can't one-time bind, the evaluation of the translation lookup expression should be of O(1) complexity and not incur any significant cost

bmhumadi commented 6 years ago

This {{:: 'KEY' | translate }}worked for me. Thank you @ajwhite. This saved me a lot of time. Do you know why <span translate=":: 'KEY'"></span> wouldn't work though?

atticoos commented 6 years ago

$translate allows you to load the localization files separate than the rest of your application bundle. This allows you to keep your bundle size small by avoiding loading every supported language, and instead load that separately.

That means when the application initially runs, the localization files may not have been downloaded yet. It can be asynchronous.

So if you perform a one-time binding before your localization files have loaded, you may see the localization keys bind to the UI and never become hydrated with the localization values.

This library aims to solve that problem.

bmhumadi commented 6 years ago

Yes, we're loading localization files separately but it takes a long time to bootstrap the app so by the time, the view is rendered, the localization files has already loaded. I tried <span translate-once="KEY"></span> but that didn't work. The span was just empty. {{:: 'KEY' | translate }}. {{:: 'KEY' | translate }} worked for me though. I am not sure why <span translate=":: 'KEY'"></span> wouldn't work.

atticoos commented 6 years ago

Yes, we're loading localization files separately but it takes a long time to bootstrap the app so by the time, the view is rendered

Just be aware that the proper network conditions is not guaranteed and can lead to unexpected behavior.

I tried <span translate-once="KEY"></span> but that didn't work. The span was just empty.

That's surprising. Is it possible the module was not injected into the application module?

Eg

angular.module('your-app', [..., 'angular-translate-once'])

Otherwise filing a separate issue with a reproducible example would be helpful

bmhumadi commented 6 years ago

Ok, got it. Thanks a lot for your help. I did forget to import the angular-translate-once module. Surprisingly, there were no errors. I will try the library again.