Reputation: 15089
I have a component (tree widget) in Angular 2.
It looks like this:
<div *ngFor="let foo in foos">
<span (click)="isCollapsed[foo.id] = !isCollapsed[foo.id]">{{ foo.name }}</span>
<div class="container" [ngClass]="{'hidden': isCollapsed[foo.id]}">
<div *ngFor="let bar in foo.bars">
<a [routerLink]=".......">{{ bar.name }}</a>
</div>
</div>
</div>
I have two levels, the second level is hidden/shown when clicked on the name of an element in the first level.
The problem is that every time I click on a node in the second level, the tree loses it's state (closed nodes get open again and viceversa).
I understand that this is because of how Angular's router is re-drawing all the components, and I know that I could hack some solution using local storage to persist the state of isCollpased
, but I'm wondering if there is a way I can make Angular remember the state of the component and apply it automatically, or even better, just reuse it somehow instead of reloading/redrawing it. Is that possible?
Upvotes: 2
Views: 1899
Reputation: 8421
To reuse the same component, you can place it outside of the router-outlet tag in AppComponent:
<your-tree-structure>...</your-tree-structure>
<router-outlet></router-outlet>
That could be acceptable for something like a main menu which is always present.
You can also use named router outlets - they allow you to have something like iframes so when you click a link in your tree, the tree structure will stay intact and the desired content will be displayed in another outlet. https://angular.io/docs/ts/latest/guide/router.html#!#milestone-4 https://github.com/onehungrymind/ng2-named-router-outlets
But the custom state serialization to sessionStorage you mentioned, is a rather simple solution too. In ngOnInit() try to load the state and in ngOnDestroy() persist it. If you need it in several components, it's possible to create a generic method that would do it for any component (using something like class-transformer TypeScript library).
Upvotes: 3