Хотите предотвратить восстановление компонентов во время маршрутизации в Angular 2

Скажем, у нас есть два маршрута Dashboard и Profile. Dashboard имеет динамические вкладки, такие как Google spreadsheet. Я хочу сделать некоторые взаимодействия (строить диаграммы, визуализировать некоторые данные), создавая вкладки в Dashboard. Теперь, если я перейду к Profile, а затем вернусь к Dashboard, я хочу увидеть, что было раньше на тех вкладках в Dashboard. Это означает, что я хочу поддерживать состояние на стороне клиента. AFAIK при маршрутизации между компонентами, он воссоздает компоненты. Возможно ли сделать таблицу как приложение при использовании маршрутизации angular 2? Мне нужно использовать маршрутизацию, потому что в моем приложении я должен использовать функцию LazyLoading.

Итак, какова должна быть идея? Я новичок в angular 2.

Ответ 1

В настоящее время компоненты повторно используются только, когда изменяются только параметры маршрута, оставаясь на одном и том же маршруте.

Если маршрут изменен, событие, когда новый маршрут добавляет один и тот же компонент, компонент воссоздается.

Предпочтительным решением является сохранение модели в общей службе, которая остается живой во время изменения маршрута, и использовать данные этой службы для восстановления предыдущего состояния компонента.

Было упомянуто, что планы поддержки пользовательских стратегий повторного использования с маршрутизатором, но не сроки, когда это станет доступным.

Обновление

Поддержка пользовательской стратегии повторного использования была добавлена ​​в Angular2.

См. также

Ответ 2

Благодаря примеру, предоставленному @Günter Zö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 {}