web-dev-qa-db-ja.com

Angular 2

DashboardProfileの2つのルートがあるとしましょう。 Dashboardには、Google spreadsheetのような動的タブ機能があります。 Dashboardにタブを作成するいくつかの相互作用(グラフの作成、データの視覚化)を実行したいと思います。ここで、Profileにルーティングしてから、Dashboardに戻ると、Dashboardのタブで以前の状態を確認したいと思います。つまり、クライアント側の状態を維持したいということです。 AFAIKは、コンポーネント間のルーティング中に、コンポーネントを再作成します。 angular 2ルーティングを使用しながらアプリケーションのようなスプレッドシートを作成することは可能ですか?アプリケーションではLazyLoading機能を使用する必要があるため、ルーティングを使用する必要があります。

では、どのようなアイデアが必要ですか? angular 2)は初めてです。

12
pd farhad

現在、コンポーネントは、同じルートに留まりながらルートパラメータのみが変更された場合にのみ再利用されますonly

ルートが変更された場合、新しいルートが同じコンポーネントを追加したときにイベントが発生すると、コンポーネントが再作成されます。

推奨される回避策は、ルート変更中にモデルを共有サービスに保持し、このサービスからのデータを使用してコンポーネントの以前の状態を復元することです。

ルーターでカスタム再利用戦略をサポートする計画があると言われましたが、これが利用可能になる時期はありません。

更新

カスタム再利用戦略のサポートがAngular2に追加されました。

も参照してください

14

@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 {}
1
Stephen Paul