【问题标题】:Reload a component with different route parameters in angular4在angular4中重新加载具有不同路由参数的组件
【发布时间】:2018-01-10 22:58:32
【问题描述】:

我正在使用 angular2 路由。当用户在搜索字段中重新输入值并点击搜索时,需要重新加载相同的组件,但路由参数不同。

<button (click)="onReload()">Search</button>

onReload() {
this.router.navigate(['results',this.location]);
}

这是我的 ResultsComponent 的路由路径

{ path:'results/:location', component:ResultsComponent}

此函数更改 URL,但不会重新初始化组件。

在angularjs,ui-router我可以这样实现。

$state.go($state.current, location, {reload: true});

如何在 angular4 中做到这一点?

【问题讨论】:

  • 我们有同样的问题:(
  • @vistajess 如果您找到解决方案,请告诉我。

标签: angular angular-routing angular-router


【解决方案1】:

您需要在 route.params 可观察流的订阅回调函数内执行订阅回调函数内的初始化逻辑。

在你的组件类中

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

   myLocation:string;

   constructor(private route:ActivatedRoute) {}

   ngOnInit() {
     this.route.params.subscribe((params:Params) => {
        this.myLocation = params['location'];
        // -- Initialization code -- 
        this.doMyCustomInitialization();
     }
   }

   private doMyCustomInitialization() {
       console.log(`Reinitializing with new location value ${this.location}`);
   }
}

另一方面,如果您需要根据“位置”的值解析数据,您应该使用解析保护,它在创建组件之前解析数据。有关解析保护和路由的更多信息,请参阅https://angular.io/guide/router#resolve-guard

这是一个有效的 plunkr。 https://plnkr.co/edit/g2tCnJ?p=preview

【讨论】:

  • 我正在订阅这些参数。我的 URL 也更改为新参数。但组件不会重新初始化。
  • 您需要在订阅回调函数中执行基于位置值的初始化逻辑。这样,每当路由更改(因此参数更改)时,都会重新执行初始化逻辑。为了提高效率,如果导航到的路由绑定到同一个组件,则 Angular 不会破坏并重新创建组件。
  • 我尝试将初始化逻辑放入订阅回调中。它仍然不起作用。此外,我的初始化逻辑是对我传递位置并获取数据的 http 服务的调用。
  • 在您的情况下,您需要使用解析防护,它可以使用位置值。请参阅我在上面的答案中发布的链接。
  • Guards 用于停止路由,直到您的异步任务完成。就我而言,异步任务需要在路由更改后完成。所以,我不知道 Resolve Guard 如何帮助我解决这个问题。
【解决方案2】:

已编辑

告诉路由器这样做的角度方式是使用onSameUrlNavigation 角度5.1

但我必须以不同的方式(Stackblitz)解决这个问题,通过subscribingroute events 并实际调用custom reInit method

诀窍是将所有订阅添加到同一个对象,然后仅当 ngOnDestroy 被 angular 调用时取消订阅,并且模板变量的其余部分从 custom destroy method 更改...

    public subscribers: any = {};

    constructor(private router: Router) {
    /** 
      * This is important: Since this screen can be accessed from two menu options 
      * 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 请求(例如)与您进入组件一样多次。

【讨论】:

  • 在简单的“使用 onSameUrlNavigation”中,如果可行,这就是@CKA 的解决方案。将其标记为正确答案。
【解决方案3】:

https://angular-2-training-book.rangle.io/handout/routing/routeparams.html

在您的组件中,您需要订阅参数以检测它们是否已更改。

【讨论】:

  • 我正在订阅参数。我的 URL 也更改为新参数。但是组件没有重新初始化
  • 感谢您的信息。我忘了在构造函数中订阅参数。
猜你喜欢
  • 1970-01-01
  • 2017-01-24
  • 2019-01-27
  • 1970-01-01
  • 2013-10-26
  • 2020-08-19
  • 2021-05-26
  • 1970-01-01
  • 2018-03-20
相关资源
最近更新 更多