Dashboard
とProfile
の2つのルートがあるとしましょう。 Dashboard
には、Google spreadsheet
のような動的タブ機能があります。 Dashboard
にタブを作成するいくつかの相互作用(グラフの作成、データの視覚化)を実行したいと思います。ここで、Profile
にルーティングしてから、Dashboard
に戻ると、Dashboard
のタブで以前の状態を確認したいと思います。つまり、クライアント側の状態を維持したいということです。 AFAIKは、コンポーネント間のルーティング中に、コンポーネントを再作成します。 angular 2ルーティングを使用しながらアプリケーションのようなスプレッドシートを作成することは可能ですか?アプリケーションではLazyLoading機能を使用する必要があるため、ルーティングを使用する必要があります。
では、どのようなアイデアが必要ですか? angular 2)は初めてです。
現在、コンポーネントは、同じルートに留まりながらルートパラメータのみが変更された場合にのみ再利用されますonly。
ルートが変更された場合、新しいルートが同じコンポーネントを追加したときにイベントが発生すると、コンポーネントが再作成されます。
推奨される回避策は、ルート変更中にモデルを共有サービスに保持し、このサービスからのデータを使用してコンポーネントの以前の状態を復元することです。
ルーターでカスタム再利用戦略をサポートする計画があると言われましたが、これが利用可能になる時期はありません。
更新
カスタム再利用戦略のサポートがAngular2に追加されました。
も参照してください
@GünterZöchbauerによって提供された例のおかげで、私自身の理解のために、最小限の例を抽出することにしました。
まとめ:
最初に私は RouteReuseStrategy を実装しました:
export class CustomReuseStrategy implements RouteReuseStrategy {
handlers: {[key: string]: DetachedRouteHandle} = {};
calcKey(route: ActivatedRouteSnapshot) {
let next = route;
let url = '';
while(next) {
if (next.url) {
url = next.url.join('/');
}
next = next.firstChild;
}
return url;
}
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return true;
}
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
this.handlers[this.calcKey(route)] = handle;
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig && !!this.handlers[this.calcKey(route)];
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!route.routeConfig) { return null; }
return this.handlers[this.calcKey(route)];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return this.calcKey(curr) === this.calcKey(future);
}
}
AppModule
内で、新しいプロバイダーを追加し、いくつかのルートを構成しました。
export const ROUTES: Routes = [
{
path: 'one',
component: OneComponent
},
{
path: 'two',
component: TwoComponent
},
];
@NgModule({
...
imports: [... RouterModule.forRoot(ROUTES)...]
providers: [...{ provide: RouteReuseStrategy, useClass: CustomReuseStrategy }...],
...
})
export class AppModule { }
最後に、いくつかのコンポーネントを次のように定義しました。
@Component({
selector: 'my-app',
template: `
<a [routerLink]="['/one']" >Route One</a><br>
<a [routerLink]="['/two']" >Route Two</a><br>
<router-outlet></router-outlet>
`
})
export class AppComponent {}
@Component({
selector: 'app-one',
template: `
Route One currently showing<br>
<input type="text" placeholder="enter some text">
`,
})
export class OneComponent {}
@Component({
selector: 'app-two',
template: `
Route Two currently showing<br>
<input type="text" placeholder="enter some text">
`,
})
export class TwoComponent {}