URL更改未在Angular中触发

时间:2018-03-07 19:01:53

标签: angular angular-routing ngonchanges

所以我的Angular应用程序有一个搜索栏,如果您在此搜索栏中输入内容,它会进行搜索并进入结果页面。一切都很好。

现在,如果您的搜索未返回任何结果,则结果页面会加载并告诉您“searchterm”未返回任何结果。此时,网址为localhost:4200/searchResults;query=searchterm。再次 - 一切都如预期的那样。

现在,如果您转到搜索栏并输入其他搜索字词,则不会发生任何事情......

嗯,这不正确...网址现在显示为localhost:4200/searchResults;query=NEWsearchterm,但由于我们在“相同的”应用页面上,因此ngOnInit不会重新启动(因此实际上会搜索该术语)NOR会对ng​​OnChanges发生火灾(因此实际上是在搜索这个词)......

路由模块似乎做了它应该做的事情,因为我们的URL确实改变了以引用新的搜索词,但是某些事情不应该发生,我不知道是什么?

这是错误的我在路由模块中缺少(虽然我不这么认为,因为URL确实发生了变化),或者我在应用页面上的Component类中缺少的东西???

2 个答案:

答案 0 :(得分:4)

告诉路由器执行此操作的角度方式是从角度5.1开始使用onSameUrlNavigation ...但我认为执行此操作仍然存在一些问题。

所以我必须以不同的方式(Stackblitz),subscribingroute events并实际调用custom reInit method来解决此问题。

诀窍是将所有订阅添加到同一个对象,然后仅在角度调用ngOnDestroy时取消订阅,并且从custom destroy method更改模板变量的其余部分...如果您没有任何订阅,也没有实现ngOnInit生命周期ehook,然后@Yazan Mehrez的答案应该这样做,但是如果你确实有订阅或使用钩子,那么你需要一个类似下面的实现来防止内存泄漏:

    public subscribers: any = {};

    constructor(private router: Router) {
    /** 
      * This is important: Since this screen can be accessed from two menu options or has query string parameter changes  
      * we need to tell angular to reload the component when this happens.
      * It is important to filter the router events since router will emit many events,
      * therefore calling reInitComponent many times wich we do not want.
      */   
      this.subscribers._router_subscription = this.router.events.filter(evt => evt instanceof NavigationEnd).subscribe((value) => { 
        this.reInitComponent();
      });
    }

    reInitComponent() {
        this.customOnDestroy();
        this.customOnInit();
    }

    customOnInit() {
        // add your subscriptions to subscribers.WHATEVERSUB here
        // put your ngOnInit code here, and remove implementation and import 
    }

    customOnDestroy() {
      // here goes all logic to re initialize || modify the component vars  
    }

    /**
     * onDestroy will be called when router changes component, but not when changin parameters ;)
     * it is importatn to unsubscribe here
     */
     ngOnDestroy() {  
       for (let subscriberKey in this.subscribers) {
          let subscriber = this.subscribers[subscriberKey];
          if (subscriber instanceof Subscription) {
            subscriber.unsubscribe();
          }
        }
     }

请注意,如果您实现了lifecylce hook ngOnInit,则应将其删除并实现自定义方法,如示例所示。

由于this角度错误,我添加了unsubscription方法。在销毁组件时,Angular实际上应该自动取消订阅router.events,但由于情况并非如此,如果您不手动取消订阅,您最终会在输入组件时多次调用http请求(例如)。

答案 1 :(得分:2)

尝试订阅路线更改

class MyClass {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
      if(val instanceof NavigationEnd){
        console.log("refreshing");
      }
    });
  }
}