Reputation: 16949
I am using angular 2 with the material design grid-list with infinite scrolling and when I select an item from the list I navigate to the detail view representing an :id in the url path. If I navigate back the list-view is reloaded and the inital state is lost.
What is the proper way of maintaining the state of the view when navigating back? Is it possible to cache the view as it is before navigation takes place?
Upvotes: 4
Views: 2503
Reputation: 3694
First, let me say that I think support for "view-state" should be a part of the framework. And it may very well be, but I haven't been able to find it as of yet. But since I need a solution now, I have decided to roll my own. Here's how it works.
I created a ViewStateService as follows. Notice that the viewState for the service is a Map of Maps. Each top level component, that can be navigated to, has a top level map entry with the component name as the key. The map at that key is used to pass down to subcomponents to both hold their saved view state and also a place to store their view state.
@Injectable()
export class ViewStateService {
viewState : Map<string, Map<string, string> > = new Map<string, Map<string, string> >();
constructor(){
}
setViewState(key : string , map : Map<string, string>){
this.viewState.set(key, map);
}
getViewState(key : string) : Map<string, string>{
return this.viewState.get(key);
}
}
Then in top level components, this service is injected. The top level component then extracts its view state in ngOnInit() by the call:
this.viewState = this.viewStateServices.getViewState("ComponentName");
This map is handed down as an input to each subcomponent (or at least the ones that need to save viewState). The subcomponents all implement OnInit and OnDestroy. In ngOnInit() they retrieve the saved view state -- if its there. And in ngOnDestroy() they save all the viewstate they want. Each subcomponent also passes the viewstate as an input to sub-subcomponents (recursively). In this way every subcomponent gets a chance to save and restore viewstate. One thing to watch out for is components that try to save a value by the same name. You can alleviate this by prefixing all fields with the component name, or some other such convention.
I have done this for my Angular app and it appears to be working satisfactorily. However, I think that the framework really ought to provide this mechanism. If and when it does (or when I figure out how it works) I plan to switch over to using it. But in the meantime, I have a solution that works.
Upvotes: 4
Reputation: 330
This is theoretically possible but I haven't tried yet.
If you put your detail view as a child route or a component, your list view component will not be destroyed on child route/component init. Then you could hide the parent component and navigate to child. Although this is not a proper solution and you must find a way to save list view's state.
Upvotes: 2