仅当导航到其他组件时,角度检测路线更改

时间:2019-01-21 20:47:52

标签: angular angular-router

我仅在导航到应用程序中的其他组件时尝试更改路线(即滚动到顶部),而不是在停留在同一组件上并且只是通过路由更改到具有不同组件的同一组件时更改视图查询参数

例如,如果我在/products?category=kitchen处并且导航到/products?category=bedroom,则不希望执行该操作(即滚动到顶部)。

这是我app.component.ts中的代码:

this.router.events.pipe(
  filter(event => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
  // Would like to check here if user navigates to different component
  if (window) window.scrollTo(0, 0);
});

有人知道我能做到吗?

3 个答案:

答案 0 :(得分:1)

我想分享一下我如何解决此问题,以防将来有人遇到类似的事情:

private componentBeforeNavigation = null;
  private setScrollToTopOnNavigation() {
    // Scroll to top only when navigating to a different component
    this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe((event: NavigationEnd) => {
      let currentRoute = this.route;
      while (currentRoute.firstChild) currentRoute = currentRoute.firstChild;
      if (this.componentBeforeNavigation !== currentRoute.component) {
        if (window) window.scrollTo(0, 0);
      }
      this.componentBeforeNavigation = currentRoute.component;
    });
  }

此代码的作用是为名为componentBeforeNavigation的组件使用私有属性,该组件最初为null,并且每次触发Navigation事件时,subscribe中的代码都会检查我现在导航的位置与上一次导航相同。如果是,则表示它是对相同组件的导航,而我不执行我的特殊操作(在这种情况下,请滚动到窗口顶部),如果不是,则表示它是对新组件的导航。 /> 重要的一件事是将要导航到的新组件存储在属性componentBeforeNavigation中,以便始终使用上一次导航对其进行更新

答案 1 :(得分:0)

编辑:

由于我不知道您的用例,因此只能假定您正在尝试实现以下目标:

在您的应用程序中,可以通过某种方式更改查询参数“类别”,例如通过单击类别。而不是

router.navigate(['/products?category=' + newlySelectedCategory]);

并可能使用

对该查询参数做出反应
import {Router, ActivatedRoute, Params} from '@angular/router';
import {OnInit, Component} from '@angular/core';

@Component({...})
export class MyComponent implements OnInit {

  category: string;

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    // Note: Below 'queryParams' can be replaced with 'params' depending on your requirements
    this.activatedRoute.queryParams.subscribe(params => {
        this.category = params['category'];
    });
  }

}

您可以这样做:

import {Router, ActivatedRoute, Params} from '@angular/router';
import {OnInit, Component} from '@angular/core';

@Component({...})
export class MyComponent implements OnInit {

  category: string;

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    // Note: Below 'queryParams' can be replaced with 'params' depending on your requirements
    this.activatedRoute.queryParams.subscribe(params => {
        this.category = params['category'];
    });
  }

  // This will probably be called from your html code
  selectCategory(category: string) {
     this.category = category;
     this.location.replaceState(`products?category=${category}`);
  }
}

这样,就不会有路由。


一种可能的方法是不进行路由,而是使用this.location.replaceState更改当前URL(假设您在构造函数中注入了private location: Location),并手动启动将在读取时执行的相同过程网址的查询参数。

答案 2 :(得分:0)

您可以订阅ActivatedRoute paramMap来完成您的工作:

this.activatedRoute.paramMap.subscribe(paramMap  =>  {
        this.router.navigate('your child route here');
    });

,并确保类别视图是products的子路由。

还代替html模板中的产品视图添加路由占位符,以放置子视图:

<router-outlet></router-outlet>

您可以了解有关嵌套routing here:的更多信息