代码之家  ›  专栏  ›  技术社区  ›  Musical Coder

URL更改不以角度触发

  •  3
  • Musical Coder  · 技术社区  · 6 年前

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

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

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

    那是不对的。。。URL现在显示 localhost:4200/searchResults;query=NEWsearchterm ,但由于我们在“同一”应用程序页面上,ngOnInit不会重新刷新(因此实际上搜索术语),ngOnChanges也不会触发(因此实际上搜索术语)。。。

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

    这是我在路由模块中缺少的错误(尽管我不这么认为,因为URL确实发生了更改),还是我在应用程序页面的组件类中缺少的错误???

    2 回复  |  直到 6 年前
        1
  •  4
  •   Lucas    6 年前

    告诉路由器这样做的角度方法是使用 onSameUrlNavigation 从angular 5.1开始。。。但我认为在实施这一点时仍然存在一些问题。

    所以我不得不用另一种方式来解决这个问题( Stackblitz ),由 subscribing route events 事实上 custom reInit method

    诀窍是将所有订阅添加到同一对象,然后仅在以下情况下取消订阅 ngOnDestroy 由angular调用,并对模板变量的其余部分进行更改 custom destroy method 。。。如果您没有任何订阅并且没有实现ngOnInit lifcycle 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钩子ngonit,则应移除它并实现如示例中所示的自定义方法。

    我添加了 unsubscription 方法,因为 this 角虫。Angular实际上应该自动从路由器退订。销毁组件时发生的事件,但由于情况并非如此,如果不手动取消订阅,则最终将调用http请求(例如)的次数与输入组件的次数相同。

        2
  •  3
  •   Toolkit    6 年前

    尝试订阅路由更改

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