I have pure pipe TranslatePipe
that translates phrases using LocaleService
that has locale$: Observable
current locale. I al
You can also create your own unpure pipe to track external changes. Check the sources of native Async Pipe to get the main idea.
All you need is to call ChangeDetectorRef.markForCheck(); inside of your unpure pipe every time your Observable return new locale string. My solution:
@Pipe({
name: 'translate',
pure: false
})
export class TranslatePipe implements OnDestroy, PipeTransform {
private subscription: Subscription;
private lastInput: string;
private lastOutput: string;
constructor(private readonly globalizationService: GlobalizationService,
private readonly changeDetectorRef: ChangeDetectorRef) {
this.subscription = this.globalizationService.currentLocale // <- Observable of your current locale
.subscribe(() => {
this.lastOutput = this.globalizationService.translateSync(this.lastInput); // sync translate function, will return string
this.changeDetectorRef.markForCheck();
});
}
ngOnDestroy(): void {
if (this.subscription) {
this.subscription.unsubscribe();
}
this.subscription = void 0;
this.lastInput = void 0;
this.lastOutput = void 0;
}
transform(id: string): string { // this function will be called VERY VERY often for unpure pipe. Be careful.
if (this.lastInput !== id) {
this.lastOutput = this.globalizationService.translateSync(id);
}
this.lastInput = id;
return this.lastOutput;
}
}
Or you even can incapsulate AsyncPipe inside your pipe (not a good solution, just for example):
@Pipe({
name: 'translate',
pure: false
})
export class TranslatePipe implements OnDestroy, PipeTransform {
private asyncPipe: AsyncPipe;
private observable: Observable;
private lastValue: string;
constructor(private readonly globalizationService: GlobalizationService,
private readonly changeDetectorRef: ChangeDetectorRef) {
this.asyncPipe = new AsyncPipe(changeDetectorRef);
}
ngOnDestroy(): void {
this.asyncPipe.ngOnDestroy();
this.lastValue = void 0;
if (this.observable) {
this.observable.unsubscribe();
}
this.observable = void 0;
this.asyncPipe = void 0;
}
transform(id: string): string {
if (this.lastValue !== id || !this.observable) {
this.observable = this.globalizationService.translateObservable(id); // this function returns Observable
}
this.lastValue = id;
return this.asyncPipe.transform(this.observable);
}
}