3

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

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

现在,如果你去搜索栏,输入一个不同的搜索词,什么都不会发生......

好吧,那是不正确的... URL 现在说localhost:4200/searchResults;query=NEWsearchterm,但是因为我们在“相同”应用程序页面上,所以 ngOnInit 不会重新触发(因此实际上是在搜索该术语),也不会 ngOnChanges 触发(因此实际上是在搜索该术语) ...

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

这是我在路由模块中遗漏的问题(尽管我不这么认为,因为 URL 确实发生了变化),还是我在应用页面的 Component 类中遗漏了什么???

4

2 回答 2

4

告诉路由器这样做的角度方式是使用角度 5.1 的onSameUrlNavigation ......但我认为实现这一点仍然存在一些问题。

所以我不得不以不同的方式(Stackblitz)解决这个问题,通过subscribing调用route events并实际调用custom reInit method.

诀窍是将所有订阅添加到同一个对象,然后仅在ngOnDestroy被 angular 调用时取消订阅,并且将模板变量的其余部分从custom destroy method...那么@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,您应该删除它并像示例中那样实现自定义方法。

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

于 2018-03-07T19:21:16.457 回答
3

尝试订阅路线更改

class MyClass {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
      if(val instanceof NavigationEnd){
        console.log("refreshing");
      }
    });
  }
}
于 2018-03-07T19:12:59.010 回答