3

In my application there are three components. 1) Map 2) Search 3) User Profile

After login by default I load MAP component then I can go any other screen using header menu link.

I want to achieve functionality like once I load the map component in the browser it shouldn't reload component again when I come back to map screen from other screen or back button. Because when I come back from other screen it's reloading all pushpin and related data and reset the user's last view on map.

Note - In map component I load map on ngOnIt event.

How can I achieve this functionality in Angular 2/4 ?

Sample screenshot it attached for reference.

enter image description here

Pushkar Rathod
  • 353
  • 2
  • 7
  • 26
  • If you navigate away from the component, then the component will be destroyed, and so will all of its bindings. If there is data you can cache then put that data into a service, so when it is loaded the first time it will never be loaded again and the cache will be used instead. – Lansana Camara Dec 18 '17 at 19:54
  • @Lansana Thanks for prompt response. Well I can't use cache here because I am getting continuous live data from rest API to show pushpin on map so I don't want to cache any single data. Only the things is the map should stay as it's previous state when come back to map component. I don't want to refresh the map. – Pushkar Rathod Dec 18 '17 at 20:25
  • Does the map you are using have any config options to save its state? If so, you should add that logic to a service, and load that save stated on init of your component so that your map can use it if it exists, otherwise create a new version of itself. This is the only way you can achieve what you want, as all state in the component itself will be destroyed, which is why your map is always recreated. – Lansana Camara Dec 19 '17 at 13:27
  • Thanks @Lansana No I don't have any state in config. Can you provide example ? sorry I am new in angular so don't know how to create and maintain state in component. – Pushkar Rathod Dec 19 '17 at 15:01
  • What map are you using? Bing maps? Does Bing maps have any API that you can configure it with? For instance wherever your code is to init bing maps, can you pass any configuration in that function call to tell it to cache the map? – Lansana Camara Dec 19 '17 at 15:03
  • @Lansana I am using Bing Map. I found something on angular.io. Do you have any idea on this? https://stackoverflow.com/questions/41280471/how-to-implement-routereusestrategy-shoulddetach-for-specific-routes-in-angular – Pushkar Rathod Dec 20 '17 at 16:06
  • Take a look at a shorter answer that is a variant of the accepted answer. Try it and see if it works for your use case, seems like it might: https://stackoverflow.com/a/44854611/4749297 – Lansana Camara Dec 20 '17 at 16:30
  • 1
    @Lansana well I got help from this example. https://plnkr.co/edit/otbZBuRmGYQXeY6b4Sfp?p=preview. Btw Thank you for your tips !! – Pushkar Rathod Dec 26 '17 at 17:15
  • Glad you got it working! :) – Lansana Camara Dec 26 '17 at 19:54

1 Answers1

3

This is how I achieved this.

First - Implemented RouteReuseStrategy interface.

import {RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {

    handlers: {[key: string]: DetachedRouteHandle} = {};

    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        //console.debug('CustomReuseStrategy:shouldDetach', route);
        return !!route.data && !!(route.data as any).shouldDetach;
    }

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        //console.debug('CustomReuseStrategy:store', route, handle);
        this.handlers[route.routeConfig.path] = handle;
    }

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        //console.debug('CustomReuseStrategy:shouldAttach', route);
        return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
    }

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        //console.debug('CustomReuseStrategy:retrieve', route);
        if (!route.routeConfig) { return null; }
        return this.handlers[route.routeConfig.path];
    }

    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        //console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
        return future.routeConfig === curr.routeConfig;
    }

}

Second - added CustomReuseStrategy provider in the app.module.

import {RouteReuseStrategy} from '@angular/router';
import {CustomReuseStrategy} from './Shared/reuse-strategy';

providers: [
{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }
]

Third - added shouldDetach attribute in app.routing.ts

import { Routes, RouterModule } from "@angular/router";
import { MapComponent } from './components/map/map.component';

const ROUTES: Routes = [
{ path: 'maps', component: MapComponent , canActivate:[AuthGuard], data: { shouldDetach: true} },
];
Pushkar Rathod
  • 353
  • 2
  • 7
  • 26
  • @Ashwin I am not sure about this solution but you can try this https://stackoverflow.com/questions/44875644/custom-routereusestrategy-for-angulars-child-module – Pushkar Rathod Jul 11 '18 at 20:24