Relative translation keys
@flyze/lib-core-angular 1.0.0-alpha.34· latestA library or a deeply nested feature module repeats its own prefix in every single key —
FLYZE_LIB_CORE_ANGULAR.I18N.MAT_PAGINATOR.FIRST_PAGE_LABEL. TranslocoRelativeHelperService holds
that prefix once and resolves keys relative to it, so call sites read 'FIRST_PAGE_LABEL'.
This is a separate mechanism from the scope in a scoped FyzTranslationConfig
(translation-config): a scope is a transloco namespace loaded from its
own file, a base path is a prefix inside an already loaded namespace.
The service
Section titled “The service”TranslocoRelativeHelperService
(transloco-relative-helper.service.ts:31)
is not providedIn: 'root' — it is deliberately provided per module or component, because the
base path is per consumer. Injecting the root instance from two features would have them fight over
setBasePath.
The base path is a BehaviorSubject, and the select* methods switchMap over it
(transloco-relative-helper.service.ts:57). That
is the reason for the extra indirection: a subscriber that subscribed before setBasePath() was
called still re-resolves against the new prefix, and a later setBasePath() re-resolves every open
subscription. The synchronous translate() reads _basePath$.value directly, so it only sees the
prefix already set.
| Method | Prefixed | Returns |
|---|---|---|
translate(key, params?, lang?) | yes | string |
translateNoBase(key) | no | string |
selectTranslate(key, …) | yes | Observable |
selectTranslateObject(key, …) | yes | Observable<object> |
selectLanguageChanged(propPath?) | no | Observable<object> |
The prefix is a plain string concatenation (`${basePath}${key}`) — no separator is
inserted. A base path must therefore end with the dot itself, or every key must start with one.
Passing '' resolves the base path as an object, which is what the paginator below relies on.
selectLanguageChanged is the odd one out: it ignores the base path, filters for object results and
debounceTime(500), and still defaults its prop path to 'BRICK_GENERATOR_LIB'
(transloco-relative-helper.service.ts:78) — a
leftover from another library. Always pass an explicit path.
createTranslateRelative
Section titled “createTranslateRelative”For code that has no injector, createTranslateRelative(basePath) returns a function closing over
the prefix and calling transloco’s standalone translate()
(transloco-relative-helper.service.ts:23). It has
the same string-concatenation caveat, is synchronous only, and requires transloco to be initialized
— useful in resolvers and factory providers, not in templates.
The paginator translation
Section titled “The paginator translation”MatPaginatorIntlTranslocoService is the one consumer shipped with the library and the working
example of the pattern
(mat-paginator-intl-translation.service.ts:9).
It extends Material’s MatPaginatorIntl, sets the base path to
FLYZE_LIB_CORE_ANGULAR.I18N.MAT_PAGINATOR, then subscribes to selectTranslateObject('') — one
subscription for the whole label block instead of six.
getRangeLabel is reassigned inside that subscription rather than overridden as a method, because
it has to close over the freshly translated RANGE_SEPARATOR. The implementation is Material’s own,
with the separator substituted for the hardcoded ' of ', including Material’s edge cases: 0
items renders 0<sep>0, and a start index past the end does not clamp the end index.
MatPaginatorIntl expects changes to be emitted when labels change; this service does not emit
it. An already-rendered paginator therefore keeps its old labels until something else re-renders it
— the labels are correct on first paint and after a language switch that triggers change detection
anyway.
The keys themselves ship in
src/lib/i18n/en.json and de.json; how
they reach a consumer app is
guides/loading-library-translations.
Related
Section titled “Related”- translation-config — scopes, the other prefixing mechanism
- guides/loading-library-translations