Пользовательский интерфейс Kendo для локализации Angular Datepicker не работает, когда модуль загружается через ngIf

Этот вопрос относится к приложению Angular 6, которое использует пользовательский интерфейс Kendo для Angular.

Недавно я работал над динамической глобализацией/локализацией компонентов Kendo DatePicker и TimePicker. В правом верхнем углу сайта, в заголовке, есть раскрывающийся список языков, в котором пользователь может динамически менять язык/язык сайта. Я хотел реализовать способ динамического обновления компонентов Kendo datepicker и timepicker для автоматического перевода текста и обновления форматов DateTime компонента Kendo в соответствии с локалью, которую пользователь выбирает из раскрывающегося списка.

Поэтому я взял компоненты Kendo DatePicker и TimePicker и поместил их в отдельный модуль под названием «DatepickerWrapperModule». И все работает нормально, пока этот модуль активно загружается (т.е. модуль и соответствующий компонент не внедряются динамически на страницу).

Однако, если модуль и соответствующий компонент динамически загружаются на страницу с помощью директивы *ngIf, это нарушает установленную мной динамическую локализацию.

Я предполагаю, что это связано с ленивой загрузкой модуля и, таким образом, созданием новых экземпляров служб, от которых он зависит??? Но, изучив и испробовав много разных вещей, чтобы заставить его работать, я пока безуспешно. Есть ли способ заставить этот тип динамической локализации Kendo UI DatePicker работать с модулями/компонентами, которые динамически загружаются через * ngIf ???

Обычно я бы предоставил все соответствующие примеры кода, но они слишком большие и сложные, чтобы их можно было кратко отобразить в этом вопросе. В общем есть:

  • AppModule
  • Общий модуль
  • и DatepickerWrapperModule

AppModule импортирует SharedModule в массив imports[] с помощью метода forRoot().

Затем SharedModule импортирует DatepickerWrapperModule в массив imports[], а также экспортирует его в массив exports[]. В массиве imports[] DatepickerWrapperModule использует метод forRoot().

Затем DatepickerWrapperModule реализует компонент DatePickerWrapper, который содержит фактические ссылки на компонент Kendo DatePicker.

Кроме того, в конструкторе DatepickerWrapperModule я использую декораторы параметров конструктора @Optional() и @SkipSelf(), чтобы увидеть, загружается ли DatepickerWrapperModule дважды, и с помощью некоторых простых операторов console.log я подтвердил, что он действительно инициализируется и загружается дважды (один раз при начальной загрузке всего приложения/сайта и один раз при выполнении условия *ngIf на конкретной странице и для конкретного рассматриваемого компонента.

Я хотел бы выяснить, как получить модуль/компонент, который загружается с помощью условия *ngIf, чтобы использовать экземпляр DatepickerWrapperModule, который уже загружен как часть всего приложения, вместо того, чтобы создавать новый его экземпляр, когда компонент динамически добавляется в DOM при выполнении условия *ngIf.

Заранее спасибо!


person Chase Harrison    schedule 15.08.2018    source источник
comment
Пробовали ли вы подход, описанный здесь   -  person SiliconSoul    schedule 16.08.2018
comment
@SiliconSoul Да, после долгих проб и ошибок я наконец нашел проблему и конкретное место, когда мне нужно было предоставить IntlService и CldrIntlService. Но да, подход, описанный в предоставленной вами ссылке, привел меня в правильном направлении и в конечном итоге решил мою проблему. Спасибо!   -  person Chase Harrison    schedule 24.08.2018


Ответы (1)


Теперь, когда я, наконец, решил свою проблему, я хотел дать ответ на свой вопрос, который решил ее для меня, на случай, если кто-то еще столкнется с этой же проблемой в будущем.

Для справки см. рекомендуемый подход, который в итоге решил мою проблему, здесь: https://github.com/telerik/kendo-angular/issues/1455#issuecomment-405247258

По сути, проблема для меня была связана с тем, как работают модули с отложенной загрузкой при загрузке через маршруты, такие как:

{
    path: 'logistics',
    canActivate: [AuthGuardService],
    appData: 'APPDATA_LOGISTICS',
    loadChildren: './logistics/+logistics/logistics.module#LogisticsModule'
}

В массиве provider[] моего AppModule я указал LOCALE_ID, CldrIntlService и IntlService следующим образом:

providers: [
    CldrIntlService,
    {
        provide: IntlService,
        useExisting: CldrIntlService
    },
    {
        provide: LOCALE_ID,
        useValue: 'en-US'
    }
]

Это предоставит эти службы для быстро загружаемых модулей, которые импортируются в AppModule или какой-либо дочерний элемент AppModule, но для лениво загружаемых модулей, которые не импортируются или не направляются дочерними элементами AppModule, будут созданы новые экземпляры этих служб.

Итак, по приведенной выше ссылке, как только я указал соответствующих провайдеров в лениво загружаемом LogisticsModule, динамическая локализация компонентов Kendo DatePicker и TimePicker снова начала работать, как и ожидалось.

Вот соответствующая часть массива provider[] в LogisticsModule, которая решила мою проблему:

providers: [

    .
    .
    .

    {
        provide: IntlService,
        useExisting: CldrIntlService
    }

    .
    .
    .

]

Это говорит LogisticsModule использовать экземпляр сервисов, уже созданных (предоставленных) в AppModule (вместо создания новых экземпляров сервисов, когда модуль загружается отложенно).

person Chase Harrison    schedule 24.08.2018