【问题标题】:angular 5.2 onSameUrlNavigation not working角度 5.2 onSameUrlNavigation 不起作用
【发布时间】:2018-08-03 07:33:48
【问题描述】:

我试图在我的 Angular 5.2 应用程序中重新加载我的导航,但没有成功。如果参数不变,角度路由器将忽略我的导航。

我如何导航:

this.router.navigate(['/search', buildParamsFromSearchCriteria(criteria)]);

这导航到:

/search;pageSize=20;page=1;orderBy=price;sortDirection=ASCENDING

我的模块配置:

imports: [RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules, enableTracing: false, onSameUrlNavigation: 'reload' })],

【问题讨论】:

  • 你看到那个帖子了吗? github.com/angular/angular/issues/21115 显然,它只用于再次运行守卫和解析器。你到底想达到什么目的?难道你不能在你的组件中有一个可以手动调用的“刷新”操作吗?
  • 我无法刷新,因为我的组件仅使用搜索参数导航。我的 ngrx 效果监听路由器调用并在导航到 url 时分派搜索操作。我现在有一个临时 hack,它在 url 的末尾设置一个随机数以使其唯一
  • 为什么要在同一个 url 上路由两次?你会得到同样的结果吗?
  • 结果可能不一样,因为后端数据可能已经更新或添加了项目。
  • 您可以再添加一个随机参数来强制刷新。

标签: angular angular5


【解决方案1】:

我在点击导航栏上的相关按钮时尝试刷新页面时遇到了同样的问题。

如 cmets 中所述,onSameUrlNavigation 仅运行守卫和解析器,但不重新初始化组件。有趣的是,它还触发了导航。

所以我创建了一个对NavigationEnd 事件做出反应的抽象类:

/**
 * Abstract class that allows derived components to get refreshed automatically on route change.
 * The actual use case is : a page gets refreshed by navigating on the same URL and we want the rendered components to refresh
 */
export abstract class AutoRefreshingComponent implements OnInit, OnDestroy {
  public routerEventsSubscription: Subscription;
  protected router: Router;

  constructor() { 
    this.router = AppInjector.get(Router);
  }

  /**
   * Initialization behavior. Note that derived classes must not implement OnInit.
   * Use initialize() on derived classes instead.
   */
  ngOnInit() {
    this.initialize();
    this.routerEventsSubscription = this.router.events.filter(x => x instanceof NavigationEnd).subscribe(res => {
      this.initialize();
    });
  }

  /**
   * Destruction behavior. Note that derived classes must not implement OnDestroy.
   * Use destroy() on derived classes instead.
   */
  ngOnDestroy(): void {
    this.routerEventsSubscription.unsubscribe();
    this.destroy();
  }

  /**
   * Function that allows derived components to define an initialization behavior
   */
  abstract initialize(): void;

  /**
   * Function that allows derived components to define a destruction behavior
   */
  abstract destroy(): void;

}

AppInjector 指的是这个:

import {Injector} from '@angular/core';

/**
 * Allows for retrieving singletons using `AppInjector.get(MyService)` (whereas
 * `ReflectiveInjector.resolveAndCreate(MyService)` would create a new instance
 * of the service).
 */
export let AppInjector: Injector;

/**
 * Helper to access the exported {@link AppInjector}, needed as ES6 modules export
 * immutable bindings; see http://2ality.com/2015/07/es6-module-exports.html
 */
export function setAppInjector(injector: Injector) {
    if (AppInjector) {
        // Should not happen
        console.error('Programming error: AppInjector was already set');
    }
    else {
        AppInjector = injector;
    }
}

在 AppModule 中:

import { setAppInjector } from './app.injector';

// ...

export class AppModule {
  constructor(private injector: Injector) {
    setAppInjector(injector);
  }
}

然后我让所有需要的组件扩展AutoRefreshingComponent 并实现需要的功能。

希望这个迟到的答案有所帮助。

【讨论】:

    【解决方案2】:

    它可以以更简单的方式完成。下面是一个小示例代码:

    在routing.module中:“/product/:id/details”

    import { ActivatedRoute, Params, Router } from ‘@angular/router’;
    
    export class ProductDetailsComponent implements OnInit {
    
        constructor(private route: ActivatedRoute, private router: Router) {
            this.route.params.subscribe(params => {
                this.paramsChange(params.id);
            });
    
        }
    
        // Call this method on page load
        ngOnInit() {
        }
    
        // Call this method on change of the param
        paramsChange(id) {
        }
    

    一般的解释是......为什么要销毁已经存在的组件实例并为相同的情况创建一个新的组件实例,这意味着性能下降?这与使用路由模式 /product/:id 的行为完全相同,其中为 /product/5、/product/6、...保留相同的组件实例。

    因此,您应该在某些发出的事件(解析器/保护)的基础上重新初始化组件,而不是在 OnInit 钩子的基础上,因为相同的组件实例。

    【讨论】:

    • 我曾尝试过这种方法,但在导航到具有相同参数的路线的情况下。它不会触发 this.route.params.subscribe(params => 的事件
    【解决方案3】:
    this.router.navigated =false
    work for me  then at ngOnInit just put this below code
    this._initise = this.router.events.pipe(
      filter((event: RouterEvent) => event instanceof NavigationEnd),
      takeUntil(this.destroyed)
    ).subscribe(() => {
      this.router.navigated = false;
      console.log('initialiseInvites')
      this.initialiseInvites();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-05-26
      • 1970-01-01
      • 2014-09-23
      • 2018-07-16
      • 2014-06-26
      • 2017-06-22
      • 2016-11-24
      相关资源
      最近更新 更多