Javascript 角度2组件不';t检测路由参数更新(路由器3.0)

Javascript 角度2组件不';t检测路由参数更新(路由器3.0),javascript,angular,angular2-routing,angular2-components,angular2-router3,Javascript,Angular,Angular2 Routing,Angular2 Components,Angular2 Router3,我有一个小的Plunk,我正在使用Angular 2中目前可用的新路由器3.0 alpha。一般来说,它工作得很好,但问题是,一旦我单击一个链接,该链接将路由到具有特定ID的“详细信息”组件,当我单击具有不同ID的不同链接时,它就不会改变。该组件永远不会被重新实例化,因此它只会在第一次加载时显示传递的内容 以下是有问题的组件: import { Component, OnInit } from '@angular/core'; import { ActivatedRoute } from '@a

我有一个小的Plunk,我正在使用Angular 2中目前可用的新路由器3.0 alpha。一般来说,它工作得很好,但问题是,一旦我单击一个链接,该链接将路由到具有特定ID的“详细信息”组件,当我单击具有不同ID的不同链接时,它就不会改变。该组件永远不会被重新实例化,因此它只会在第一次加载时显示传递的内容

以下是有问题的组件:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ContactsService } from './contacts.service';

@Component({
  selector: 'contacts-detail',
  template: `
    <h2>{{contact.name}}</h2>
  `
})
export class ContactsDetailComponent implements OnInit { 

  constructor(private contactsService: ContactsService, private route: ActivatedRoute) {
  }

  ngOnInit() {
    this.contact = this.contactsService.getContact(this.route.snapshot.params.id);
    console.log('Fetching user', this.route.snapshot.params.id);
  }
}
从'@angular/core'导入{Component,OnInit};
从'@angular/router'导入{ActivatedRoute};
从“/contacts.service”导入{ContactsService};
@组成部分({
选择器:“联系人详细信息”,
模板:`
{{contact.name}
`
})
导出类ContactsDetailComponent实现OnInit{
构造函数(专用联系人服务:联系人服务,专用路由:ActivatedRoute){
}
恩戈尼尼特(){
this.contact=this.contactsService.getContact(this.route.snapshot.params.id);
log('Fetching user',this.route.snapshot.params.id);
}
}

演示问题。单击一个作者姓名,然后单击另一个作者姓名,以确保其不会更改。

在您的
联系人DetailComponent
中,将
OnInit更改为:

ngOnInit() {
    this.sub = this.route.params.subscribe(params => {
     let id = +params['id']; 
     this.contact = this.contactsService.getContact(id);
   });
  }

在您的Plunk中为我工作。

似乎有多个生命周期挂钩可用于此。我使用
DoCheck
接口并在组件类中实现相关的
ngDoCheck()
方法,成功地获得了所需的行为,如下所示

import { Component, DoCheck } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ContactsService } from './contacts.service';

@Component({
  selector: 'contacts-detail',
  template: `
    <h2>{{contact.name}}</h2>
  `
})
export class ContactsDetailComponent implements AfterViewChecked, DoCheck { 

  constructor(private contactsService: ContactsService, private route: ActivatedRoute) {
  }

  ngDoCheck() {
    this.contact = this.contactsService.getContact(this.route.snapshot.params.id);
  }
}
从'@angular/core'导入{Component,DoCheck};
从'@angular/router'导入{ActivatedRoute};
从“/contacts.service”导入{ContactsService};
@组成部分({
选择器:“联系人详细信息”,
模板:`
{{contact.name}
`
})
导出类ContactsDetailComponent实现AfterViewChecked,DoCheck{
构造函数(专用联系人服务:联系人服务,专用路由:ActivatedRoute){
}
ngDoCheck(){
this.contact=this.contactsService.getContact(this.route.snapshot.params.id);
}
}
使用更新的代码


不过,我不认为这是最好/正确的生命周期挂钩。也许
路由器中有某种钩子可以更好地服务于此。

另一种方法:

ngOnInit() {
    this.route.params.forEach((params: Params) => {
      let id = +params['id']; 
      this.contact = this.contactsService.getContact(id);
    });
}

在这里,从一个可观察对象中检索路由参数。使用可观察快照的优点是重用组件而无需再次实例化。根据Angular 2.0最终文档,这似乎是推荐的方法。

这对我来说确实有效,但似乎有些奇怪。不过,如果没有别的事情发生,我会同意的。非常感谢您花时间回答。这并不奇怪,这是组件重用。@TDaver让我更改我的用词;这一点都不明显。我找了一个类似ngOnReload的界面来使用,但什么也没找到。这似乎是一种更具角度的方式来做需要做的事情。@t请看我对这个问题的回答。它使用
ngDoCheck()
捕获更改。不过,我不知道它是否是要使用的精确的生命周期挂钩。我认为它会在一个非琐碎的组件中频繁触发。在我的回答中,Plunk展示了它的使用情况。这是一种有趣的方法(而且显然是有效的)。从
DoCheck
周围的一小部分文档来看,它似乎是用于指令的。知道从快照获取参数值相对于从可观察到的参数值是否有优势吗?@R.Richards我不确定这是否正确。我对组件中的表单字段进行了测试,表单字段与
@Input
变量相关联,并且在输入字段中的每次击键时触发
ngDoCheck()
方法,这显然不是我们真正想要的。只是“感觉”应该有更好的东西,但我确实看到一篇文章(不是官方)提到新路由器希望人们像你在回答中那样处理这种情况……哇。谢谢你@Michael Oryl!!我想请你喝杯咖啡。我一直试图让我的一个组件在其值发生变化时刷新自己,在多次尝试之后,我几乎完全放弃了。我试着按照您的建议实现ngDoCheck()方法,现在它可以正常工作了。中提琴。几个小时的挫折现在已经结束。