【问题标题】:Want to prevent Component recreation while routing in Angular 2想要在 Angular 2 中路由时防止组件重新创建
【发布时间】:2017-02-07 07:38:01
【问题描述】:

假设我们有两条路线DashboardProfileDashboard 具有动态标签功能,例如 Google spreadsheet。我想做一些交互(构建图表,可视化一些数据)在Dashboard 中创建选项卡。现在,如果我路由到Profile,然后再路由回Dashboard,我想看看Dashboard 中的这些选项卡之前的内容。这意味着,我想保持客户端的状态。 AFAIK 在组件之间路由时,它会重新创建组件。是否可以在使用 Angular 2 路由时制作类似应用程序的电子表格?我需要使用路由,因为在我的应用程序中我必须使用 LazyLoading 功能。

那么这个想法应该是什么?我是 Angular 2 的新手。

【问题讨论】:

  • 我认为可以通过路由实现。我已阅读此博客,但我自己并没有尝试实现您寻求的这种高级路由。 vsavkin.com/angular-2-router-d9e30599f9ea#.2o8b488po
  • 我阅读了博客和 vsavkin 的新书。但这对我来说太复杂了,无法理解这个概念。这就是为什么我正在寻求更好、更容易理解的原因:/

标签: angular angular2-routing angular2-router3


【解决方案1】:

感谢@Günter Zöchbauer 提供的示例,出于我自己的理解,我决定提炼一个最小的示例。

See it in action

总结:

首先我实现了一个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 {}

【讨论】:

    【解决方案2】:

    目前在保持相同路由时仅在路由参数发生变化时重用组件。

    如果路由发生变化,当新路由添加相同组件时,该组件被重新创建。

    首选的解决方法是将模型保存在共享服务中,该服务在路由更改期间保持活动状态,并使用来自该服务的数据来恢复组件的先前状态。

    有人提到,有计划支持路由器的自定义重用策略,但没有时间表何时可用。

    更新

    Angular2 添加了对自定义重用策略的支持。

    另见

    【讨论】:

    • 但是根据我的要求,我需要在Dashboard下创建多个标签(甚至可能像google电子表格一样有100个标签)。那我该怎么办?你能对RouterState有所了解吗?
    • 我不认为RouterState 是相关的。您可能希望查看 aux-routes 并且不要离开当前路线以显示 Profile 而是将其显示为模态或类似的。辅助路由支持对我来说似乎仍然有点受限(虽然还没有对它们进行太多实验)。
    • 我以Profile 为例:/但我的应用程序就像在标签中构建交互,如谷歌电子表格,并将这些标签存储在Dashboard 中。我需要延迟加载。我的要求很复杂,我在初始架构上遇到了问题:(
    • 你现在可能会忽略这个限制,并希望 Angular 团队最终会提供一个解决方案,就像 github.com/angular/angular/issues/7757#issuecomment-236737846 中提到的那样
    • 您也可以将&lt;router-outlet&gt; 组件替换为自定义组件,该组件不会删除特定组件,而只会隐藏它们。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2018-03-20
    • 2022-01-15
    相关资源
    最近更新 更多