Действовать, когда ленивый загруженный модуль уничтожен - PullRequest
0 голосов
/ 29 августа 2018

У меня есть приложение Angular 6, и я лениво загружаю модуль и передаю некоторые данные через маршрутизатор. Оказавшись в модуле, я вызываю метод в общем сервисе, которому я передаю эти данные (данные конфигурации).

Мне нужно вызвать метод, когда этот модуль уничтожен (по сути, когда пользователь покидает этот путь), но я хочу вызвать его только один раз, поэтому я хочу избежать необходимости постоянно наблюдать за изменением маршрута, так как это будет дорого. Причина в том, что мне нужно сбросить конфигурацию общего сервиса. По сути, у меня есть определенные данные конфигурации для приложения, и мне нужно переопределить их для модуля с отложенной загрузкой, но вернуть их обратно, когда пользователь не находится в модуле.

Я пытаюсь вызвать функцию на хуке OnDestroy модуля, но она не срабатывает.

Модуль маршрутизации:

const appRoutes: Routes = [
    {
        path: 'lazy',
        loadChildren: 'lazy.module#LazyModule',
        data: {
            test: 'data'
        }
    },
    {
        path: 'home',
        loadChildren: 'home.module#HomeModule',
    },
{
        path: '**',
        redirectTo: '/home'
    }
]

Ленивый загруженный модуль:

export class LazyModule implements OnDestroy {

    constructor() {
        console.warn('LazyModule launched!'); // I see this
    }

    ngOnDestroy() {
        console.warn('destroyed'); // This is not triggered
    }

}

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Начиная с угловых 6 модулей никогда выгрузить.

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

Маршрутизатор просто загружает модуль, но не управляет его жизненным циклом. Даже если бы вы могли уничтожить модуль, он не освободил бы много памяти. Lazy загруженные модули управляются пакетами WebPack, которые загружаются с SystemJS. После загрузки они остаются в памяти. Даже если Angular уничтожит экземпляр модуля, исходный код пакета остается в кеше памяти SystemJS загруженных пакетов.

Эта проблема распространяется на библиотеки поставщиков. Если у вас есть модуль с отложенной загрузкой, который использует стороннюю графическую библиотеку, такую ​​как D3, то эта библиотека поставщика будет загружена, и вы не сможете ее выгрузить.

Если вам нужны провайдеры, которые существуют только для определенных маршрутов, вам следует использовать провайдеров представления.

@Component({
     ...
     viewProviders: [
         LazyFeatureService
     ]
})
export class MyLazyComponent {}

Когда вы используете вышеупомянутый компонент в качестве компонента маршрутизатора, служба LazyFeatureService создается, когда модуль загружается с отложенной загрузкой, но когда компонент уничтожается, служба также уничтожается. В следующий раз, когда пользователь посетит ленивый маршрут, сервис снова будет создан.

Обновление:

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

Этого можно добиться с помощью обработчиков canActivate и canDeactivate в маршруте.

В конфигурации вашего маршрута для ленивого модуля создайте маршрут верхнего уровня для обработки активаций.

const routes: Routes = [
    {
        path: '',
        canActivate: [ConfigActivator],
        canDeactivate: [ConfigActivator],
        children: [
            // move the routes here
        ]
    };

Затем вы можете определить активатор следующим образом.

 @Injectable()
 export class ConfigActivator implement CanActivate, CanDeactivate<any> {
       public constructor(private config: MyConfigService) {
       }

       public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
           this.config.lazyModuleLoaded();
           return true;
       }

       public canDeactivate(component: any, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot, nextState?: RouterStateSnapshot): boolean {
           this.config.lazyModuleUnloaded();
           return true;
       }
 }

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

0 голосов
/ 29 августа 2018

Модули не уничтожаются после их отложенной загрузки, но вы можете реализовать OnDestroy для компонента, который загружается модулем.

Какой бы компонент в вашем модуле с выходом маршрутизатора не создавал и не разрушал во время навигации.

Какой компонент содержит

<router-outlet></router-outlet>

И в TypeScript для этого компонента реализуйте OnDestroy, и он вызовет метод ngOnDestroy.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...