2016-08-16 74 views
17

我目前正在编写我的第一个Angular 2应用程序。 我有具有以下简单的模板的OverviewComponent:角2更改参数的路线

<div class="row"> 
    <div class="col-lg-8"> 
    <router-outlet></router-outlet> 
    </div> 
    <div class="col-lg-4"> 
    <app-list></app-list> 
    </div> 
</div> 

访问到/overview网址/我的路由器重定向我然后加载路由器,出口内的地图时。 有一个可点击的项目列表,触发一个<app-detail>而不是应用程序组件。因此,我在URL中传递引用的json文件的id:/details/:id(在我的路线中)。

上述所有工作完全正常的。如果我现在点击其中一个列表项目,将显示详细信息,但是当我选择另一个列表元素时,视图不会更改为新的详细信息。网址确实发生了变化,但内容未重新加载。我如何实现DetailComponent的重新初始化?

回答

18

按照第一最终释放,这是解决。

就非常重视正确重置组件的状态,当参数变化

this.route.params.subscribe(params => { 
    this.param = params['yourParam']; 
    this.initialiseState(); // reset and set based on new parameter this time 
}); 
+0

虽然这是一个建议的解决方案,但我遇到的问题是我的组件(具有上面的代码实现)在路由更改后加载,因此此承诺中的代码未被解雇 –

+0

您是否可以共享代码段为了我明白? – gpanagopoulos

+1

这是迄今为止更优雅和angulary的解决方案,虽然我宁愿更换'resetComponentState()'通过一个更广义的'initialize'函数,这个函数在组件被创建或参数改变时被调用。 – hGen

2

这目前不直接支持。另请参见https://github.com/angular/angular/issues/9811

你可以做的是一样的东西

<div *ngIf="doShow" class="row"> 
    <div class="col-lg-8"> 
    <router-outlet></router-outlet> 
    </div> 
    <div class="col-lg-4"> 
    <app-list></app-list> 
    </div> 
</div> 
doShow:boolean: true; 

constructor(private _activatedRoute: ActivatedRoute, private _router:Router, private cdRef:ChangeDetectorRef) { 
    _router.routerState.queryParams.subscribe(
    data => { 
     console.log('queryParams', data['st']); 
     this.doShow = false; 
     this.cdRef.detectChanges(); 
     this.doShow = true; 
    }); 
} 

(未测试)

+0

谢谢,但我解决了这个问题一个不同的方式,看我的答案。 – hGen

6

我不知道是否有这个问题的答案相似一个我要在这里提出,所以无论如何,我会做到这一点:

我设法实现了“假”重装下面的方式。

我基本上没有创造它重定向我的“真实”组件的组件我想用:

@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); 
    } 

} 

因此通过选择列表项的路由器将定位/fake/:id刚刚提取的ID从URL导航到“真实”组件。

我知道有可能是一个更简单,更奇特的方式,但我认为这个解决方案工作得很好,因为假的并没有真正引起人们的关注。只是当页面重新加载时的'闪烁'是一个消极的方面,但就我的CSS知识到达那里可能会有一些转变来覆盖这一点。

+0

嗯,非常感谢这个提示! Angular在默认情况下不支持这种事件是一件令人遗憾的事情。 – YoannFleuryDev

+0

已经有6个月了吗?我目前正在使用你的方法,但它不是很友善。 –

+0

@RaymondtheDeveloper不是我会知道的。我今天又遇到了这个问题,并给了谷歌另一个结果完全相同的结果。 – hGen

2

我使用情况下,如果子组件发送一个新的链接,并发出一个事件,那么家长可以发现变化并调用一些重载功能,这将重新加载必要的数据解决它。 另一种选择是订阅route parameters, and found when it change 但我认为,从angular2的家伙应该考虑增加参数到router.navigate功能,可以强制重装。 (forceReload =真)

2

可以检测的参数的任何更改接收的,在我的情况下,我用解决,所以我加载信息不需要该参数(只有检测到它改变)。这是我的最终解决方案:

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(); 
    } 
} 
+1

我不认为需要取消订阅,因为路由器管理它提供的观察对象并本地化订阅。当组件被销毁时清理它们。请参阅:https://angular.io/tutorial/toh-pt5#do-you-need-to-unsubscribe –

2

此处应该加入是提供RouteReuseStrategy到你的模块另一种选择。

providers: [ 
    { 
    provide: RouteReuseStrategy, 
    useClass: AARouteReuseStrategy 
    } 
] 

路由器的默认行为是重复使用的路由配置是否相同(这是当只有改变的情况下:在这个问题上的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 
} 
} 

我已经写了一些关于它在这里太:为快速反应

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