首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Angular2+ routeReuseStrategy生命周期挂钩

Angular2+ routeReuseStrategy生命周期挂钩
EN

Stack Overflow用户
提问于 2017-10-02 04:28:01
回答 2查看 2K关注 0票数 10

我试图利用自定义的RouteReuseStrategy,为此,当组件被分离时,我想挂起任何订阅,以及其他事情,比如滚动到正确的位置。

我已经检查了可能的钩子,但显然没有添加额外的生命周期钩,也没有调用OnDestroy

我尝试添加我自己的onDetach和onAttach挂钩,但是ActivatedRouteSnapshotsDetachedRouteHandle都不会给我当前组件的实例(只是原型?)。

使用CanDeactivate防护导航时,我可以掌握组件实例的唯一方法,但这似乎不对。我仍然找不到为onAttach添加钩子的方法。

因此,我的问题是,分离时如何正确地挂起组件,并在附加时恢复组件?

过去@angular/router中有一个@angular/router钩子接口,但是它似乎已经消失了,我没有看到任何替代。

P.S.似乎有一些报告称,当使用较长时间时,自定义RouteReuseStrategies的速度会减慢,这可能是因为无法暂停/恢复组件。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-03 15:18:03

我修复了它(是的,这与其说是一个缺失的特性,不如说是一个bug )。

扩展RouterOutlet并覆盖attach()detach() (见下文),然后用<app-router-outlet>替换<router-outlet>标记。如果组件有一个onDetach和/或onAttach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute)方法,它将被调用。

代码语言:javascript
复制
import {ComponentRef, Directive} from '@angular/core';
import {ActivatedRoute, RouterOutlet} from '@angular/router';

@Directive({
  selector: 'app-router-outlet',
})
export class AppRouterOutletDirective extends RouterOutlet {

  detach(): ComponentRef<any> {
    const instance: any = this.component;
    if (instance && typeof instance.onDetach === 'function') {
      instance.onDetach();
    }
    return super.detach();
  }

  attach(ref: ComponentRef<any>, activatedRoute: ActivatedRoute): void {
    super.attach(ref, activatedRoute);
    if (ref.instance && typeof ref.instance.onAttach === 'function') {
      ref.instance.onAttach(ref, activatedRoute);
    }
  }
}

即使有了这个自定义的RouteReuseStrategies,如果没有对history statesActivatedRoute中保存的data的访问,也无法用相同的routeConfig/path来标识两个实例。

与对RouteReuseStrategy、路由器导航事件和history.pushState的角调用的一些奇怪的定时相结合,编写解决方案非常困难。

这是非常令人沮丧的工作。

票数 10
EN

Stack Overflow用户

发布于 2021-09-28 10:19:55

我扩展了Su的答案,使其不直接使用指令扩展路由器出口,只需使用一个额外的属性来添加生命周期挂钩。

这将使添加额外的生命周期挂钩在应用程序中减少侵入性。

代码语言:javascript
复制
@Directive({
  selector: '[appRouteReuseLifecycle]',
})
export class RouteReuseLifeCycleDirective {
  constructor(private routerOutlet: RouterOutlet) {
    // Methods need to be patched before content init
    this.patchMethods();
  }

  /**
   * This method patches both onDetach and onAttach methods to call the relevant
   * hooks in the child component before or after running the existing logic
   * @private
   */
  private patchMethods() {
    // Save the original attach method
    const originalAttach = this.routerOutlet.attach;
    // Override the component method
    this.routerOutlet.attach = (ref: ComponentRef<any>, activatedRoute: ActivatedRoute) => {
      originalAttach.bind(this.routerOutlet)(ref, activatedRoute);
      // Call the onAttach hook if exists
      const instance = this.routerOutlet.component as ComponentWithOptionalLifecycleHooks;
      if (instance && typeof instance.onAttach === 'function') {
        instance.onAttach();
      }
    };

    // Save the original detach method
    const originalDetach = this.routerOutlet.detach;
    this.routerOutlet.detach = () => {
      const instance = this.routerOutlet.component as ComponentWithOptionalLifecycleHooks;
      if (instance && typeof instance.onDetach === 'function') {
        instance.onDetach();
      }
      // return the detached component with the original method
      return originalDetach.bind(this.routerOutlet)();
    };
  }
}

interface ComponentWithOptionalLifecycleHooks {
  onAttach?: () => void;
  onDetach?: () => void;
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46519512

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档