参数改变时的Angular 2重载路由

hGe*_*Gen 45 typescript angular2-routing angular

我目前正在编写我的第一个Angular 2应用程序.我有一个OverviewComponent,它有以下简单的模板:

<div class="row">
  <div class="col-lg-8">
    <router-outlet></router-outlet>
  </div>
  <div class="col-lg-4">
    <app-list></app-list>
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

当访问网址时,/我的路由器会将我重定向到我/overview,然后在路由器插座中加载地图.它<app-list>有一个可点击的项目列表,用于触发<app-detail>显示而不是应用程序组件.因此我在url中传递引用json文件的id :( /details/:id在我的路由中).

所有上述工作完全没问题.如果我现在单击其中一个列表项,则显示详细信息,但是当我选择另一个列表元素时,视图不会更改为新的详细信息.URL确实更改但内容未重新加载.如何实现DetailComponent的重新初始化?

Nik*_*Nik 94

您可以直接在组件级别更改routeReuseStrategy:

constructor(private router: Router) {

      // force route reload whenever params change;
      this.router.routeReuseStrategy.shouldReuseRoute = () => false;

}
Run Code Online (Sandbox Code Playgroud)

同样,可以在全球范围内更改重用策略.

这不一定直接解决你的问题,但看看这个问题是第一个搜索结果" 角度2重新加载网址如果查询参数更改 "它可能会保存下一个人挖掘github问题.

  • 这在全球范围内覆盖了路由重用策略,而不仅仅是当前组件 - 请谨慎使用此方法。 (10认同)
  • 非常感谢你。我会补充一点,在全局添加此更改后,您 ** 真的** 检查您的所有路由是否都正常,因为我的一个不再工作了。 (3认同)
  • 在搜索了一段时间后,我用角度7对我有效。谢谢。 (2认同)
  • 请小心,这种方法会破坏 routerLinkActive 指令。 (2认同)
  • 此设置使布局组件在导航时被销毁并重新加载。如果在布局组件上调用API,这将是一个昂贵的过程。 (2认同)

gpa*_*los 45

根据第一个最终版本,这已得到解决.

当参数改变时,要特别注意正确地重置组件的状态

this.route.params.subscribe(params => {
    this.param = params['yourParam'];
    this.initialiseState(); // reset and set based on new parameter this time
});
Run Code Online (Sandbox Code Playgroud)

  • 'route'是指ActivatedRoute的一个实例 (3认同)
  • 这是迄今为止更优雅和有角度的解决方案,尽管我更愿意通过更通用的 `initialize` 函数交换 `resetComponentState()`,该函数在创建组件或更改参数时被调用。 (2认同)

小智 14

在 Angular 7 项目中导入路由器。

import { Router } from '@angular/router';
Run Code Online (Sandbox Code Playgroud)

创建路由器的对象

constructor(private router: Router) {

}
Run Code Online (Sandbox Code Playgroud)

使用 routeReuseStrategy 检测路由器参数变化

ngOnInit() {
    this.router.routeReuseStrategy.shouldReuseRoute = () => {
      // do your task for before route

      return false;
    }
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*sen 12

此处应添加的另一个替代方法是为您的模块提供RouteReuseStrategy.

providers: [
  {
    provide: RouteReuseStrategy,
    useClass: AARouteReuseStrategy
  }
]
Run Code Online (Sandbox Code Playgroud)

如果配置相同,则路由器的默认行为是重用路由(在此问题中仅更改:id param时就是这种情况).通过将策略更改为不重用路由,将重新加载组件,并且您不必订阅组件中的路由更改.

RouteReuseStrategy的实现可能是这样的:

export class AARouteReuseStrategy extends RouteReuseStrategy {
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  store(route: ActivatedRouteSnapshot, handle: {}): void {

  }
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return false;
  }
  retrieve(route: ActivatedRouteSnapshot): {} {
     return null;
 }
 shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
   return false; // default is true if configuration of current and future route are the same
 }
}
Run Code Online (Sandbox Code Playgroud)

我也在这里写了一些关于它的文章:

https://pjsjava.blogspot.no/2018/01/angular-components-not-reloading-on.html

  • 这应该是一个可以接受的答案,因为它不需要更改组件行为并且可以全局定义。 (2认同)

hGe*_*Gen 7

我不知道这个问题的答案是否与我将要提出的问题类似,所以无论如何我都会这样做:

我设法通过以下方式实现'假'重装.

我基本上做的是创建一个组件,将我重定向到我想要使用的"真实"组件:

@Component({
  selector: 'camps-fake',
  template: ''
})
export class FakeComponent implements OnInit {

  constructor(private _router:Router,
              private _route:ActivatedRoute)
  { }

  ngOnInit() {
    let id:number = -1;
    this._route.params.forEach((params:Params) => {
      id = +params['id'];
    });

    let link:any[] = ['/details', id];
    this._router.navigate(link);
  }

}
Run Code Online (Sandbox Code Playgroud)

因此,通过选择列表项,路由器将导航到/fake/:id只从URL中提取id并导航到"真实"组件.

我知道可能有一种更简单,或更花哨的方式,但我认为这种解决方案效果很好,因为假的并没有引起人们的注意.当页面重新加载时只是"闪烁"是一个消极的方面,但就我的css知识到达时,可能会有一些过渡来覆盖它.


Abd*_*zad 7

在您的 constructor()

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
Run Code Online (Sandbox Code Playgroud)


Ale*_*rra 5

可以检测接收到的参数中的任何更改,在我的情况下,我使用Resolve加载信息,因此我不需要该参数(仅检测它是否更改)。这是我的最终解决方案:

public product: Product;
private parametersObservable: any;

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.parametersObservable = this.route.params.subscribe(params => {
    //"product" is obtained from 'ProductResolver'
    this.product = this.route.snapshot.data['product'];
  });
}

//Don't forget to unsubscribe from the Observable
ngOnDestroy() {
  if(this.parametersObservable != null) {
    this.parametersObservable.unsubscribe();
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不认为需要取消订阅,因为路由器可以管理其提供的可观察对象并本地化订阅。销毁组件后将它们清理干净。请参阅:https://angular.io/tutorial/toh-pt5#do-you-need-to-unsubscribe (2认同)

cyp*_*unk 5

this.route.paramMap.subscribe(params => {
  //fetch your new parameters here, on which you are switching the routes and call ngOnInit()
  this.ngOnInit();
 });
Run Code Online (Sandbox Code Playgroud)

您只需要从 paramMap 内部调用 ngOnInit() ,它将使用新加载的数据初始化整个页面。