问题
Structure Question
I'm not quite sure If I found the right place for this 2 code lines:
providers: [
{ provide: MAT_DATE_LOCALE, useValue: 'de-DE' },
{ provide: DateAdapter, useClass: CustomDateAdapter, deps: [MAT_DATE_LOCALE, Platform] }
]
Currently they are in my material.module => which is imported in shared.module => which is imported in app.module and every lazy loaded module.
CustomDateAdapter:
@Injectable()
export class CustomDateAdapter extends NativeDateAdapter {
subscription: any;
format(date: Date, displayFormat?: string | Object): string {
if (!this.subscription) {
this.subscription = appLocale.subscribe(v => {
this.setLocale(v);
})
}
return super.format(date, displayFormat);
}
}
the appLocal is in my translation Service:
export const appLocale: BehaviorSubject<string> = new BehaviorSubject('de');
(I found this code working here: Blitz)
My situation is - I have a datepicker and I can switch language between three languages without reloading the site.
My problem - I have a global service for translation - so it's not like in the stackblitz above that I'm changing language in the component because this is a dropdown in the app.component. As I import material in app.module and lazy loaded module (where the datepicker is) this couldn't work because I had two instances of CustomDateAdapter and just changed the app.component one. (I hope I understood this import/export/providers stuff right..)
I think I fixed that with the BehaviorSubject and the subscription.. but is this the right way to do this? I just want to register the two providers one time globally.
Error Question
Sorry for the long structure question as it is acutally working. Unfortunately I'm getting this error.
osp-error-handler.ts:12 RangeError: Maximum call stack size exceeded
at BehaviorSubject.push../node_modules/rxjs/internal/Observable.js.Observable._trySubscribe (Observable.js:51)
at BehaviorSubject.push../node_modules/rxjs/internal/Subject.js.Subject._trySubscribe (Subject.js:102)
at BehaviorSubject.push../node_modules/rxjs/internal/Observable.js.Observable.subscribe (Observable.js:30)
at CustomDateAdapter.push../src/app/shared/plugins/material/mat-datepicker.ts.CustomDateAdapter.format (mat-datepicker.ts:40)
at MatDatepickerInput.push../node_modules/@angular/material/esm5/datepicker.es5.js.MatDatepickerInput._formatValue (datepicker.es5.js:3259)
at MatDatepickerInput.set [as value] (datepicker.es5.js:2961)
at SafeSubscriber._next (datepicker.es5.js:2900)
at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:196)
at SafeSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.SafeSubscriber.next (Subscriber.js:134)
at Subscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._next (Subscriber.js:77)
The error just happens first time I open the page with the datepickers. When I change the date or switching route it doesn't happen again. I think there is something wrong with:
return super.format(date, displayFormat);
I hope someone can help :)
Edit 1 - error fixed:
Changed the format function to:
format(date: Date, displayFormat?: string | Object): string {
let loc = appLocale.getValue();
if (this.locale !== loc)
this.setLocale(loc);
return super.format(date, displayFormat);
}
Thanks to Sergey leading me into the right direction. If you subscribe to an BehaviorSubject you will get a lot of change calls (even if it is the same value -don't exactly know why). As it is not working without the if I think If you call setLocale the format func gets called again because of a change trigger inside - so you would never get out of this..
来源:https://stackoverflow.com/questions/56054960/angular-material-datepicker-lazy-loading-customdateadapter-internationaliz