2016-08-20 81 views
1

我有类似以下的路由:page/:id,它为每个id加载不同的内容。但是,每当我转到其他页面时,它都会重新加载整个内容。我只想重新加载来自API的数据。停止重新加载路由更改中的全部内容

导航:

<ul> 
<li [routerLink]="['/page', 1]">Page 1</li> 
<li [routerLink]="['/page', 2]">Page 2</li> 
<li [routerLink]="['/page', 3]">Page 3</li> 
</ul> 

模板: <h1 *ngIf="data">{{data.name}}</h1>

组件:

export class DataComponent implements OnInit { 

    data: any; 
    error: any; 

    constructor(
    private route: ActivatedRoute, 
    private service: DataService 
) {} 

    ngOnInit() { 
    this.getData(); 
    } 

    getData() { 
    this.service.getData() 
     .subscribe(
     res => this.data = res, 
     error => this.error = error 
    ); 
    } 

} 

如果你去这个Plunker,你会看到黑色矩形闪烁每次路由变化。理想情况下,黑色部分将保持不变,只有内部的数据会发生变化。

我也注意到这种闪烁的行为只发生在我使用HTTP调用时。如果我在该组件中有其他东西,那么在更改路线时不会发生这种情况。

有关如何解决此问题的任何想法?

编辑Here's a Plunkr显示预期的行为。但是,我使用的前ROUTER_DIRECTIVES,现在已弃用。

回答

0

延长@罗布的答案,我确实设法解决这个问题,使用Resolve后卫。但是,我在执行过程中犯了一些错误。

我创建了一个新的data-resolve,我初始化路线之前解决HTTP电话:

@Injectable() 
export class DataResolve implements Resolve { 

    constructor(private service: DataService, private router: Router) {} 

    resolve(route: ActivatedRouteSnapshot): 
    Observable<any> | Promise<any> | any { 
     return this.service.getData().then(data => { 
     if (data) { 
      return data; 
     } else { 
      this.router.navigate(['/page/1']); 
     return false; 
     } 
    }); 
    } 
} 

然后,我需要的是服务添加到我的模块供应商:

providers: [DataService, DataResolve]

并且还告诉路由解决方案,在加载路由之前:

resolve: { pages: DataResolve }

在那之后,我有一个数组,我可以在我的组件使用来获得数据:

this.route.data.forEach((data: {pages}) => { 
    this.data = data.pages; 
}); 

我也更新了我的Plunker有工作的例子。

0

您已经只是重新加载来自API的内容。黑盒子闪烁是因为你正在设计h1h1正在改变。如果您想为每个页面提供该框,请将其移至AppComponent的模板。

<div class="box"> 
    <router-outlet></router-outlet> 
</div> 

然后移动样式的.box选择,而不是h1

另一个问题是盒子的高度会在内容被移除和刷新时崩溃和扩大。您可以通过在路线上使用解决方案来解决此问题。发生

https://angular.io/docs/ts/latest/guide/router.html#!#resolve-guard

+0

我明白了。但是,我想知道是否没有其他办法。如果我有更复杂的结构,我仍然会遇到同样的问题:黑盒会保留,但其内部的其他静态信息仍会闪烁。我也注意到,只有当我使用HTTP调用时才会发生这种行为。如果我在该组件中有其他东西,在更改路线时它不会闪烁。 – brians69

+0

如果您使用解析警卫,它不应该闪烁,因为在http请求从服务器解析之前,路由不会被加载。 – Rob

+0

也许我做错了什么?我更新了我的Plunker:http://plnkr.co/edit/8l2GwRzhcVKF4xUea55o?p=preview – brians69

1

你眨眼,因为当你浏览,DataComponent被破坏并重新修建,但它无法显示,直到新的数据从服务器,因为你阻止其与*ngIf="data"显示到达。 On this plunker,我在服务器响应中添加了1秒的延迟,使问题变得明显。请注意,只有DataComponent闪烁。其余的PagesComponent没有。

On this plunker,没有可见的闪烁,因为数据是硬编码的,所以没有等待服务器的响应。

为了减轻闪烁,不要使用*ngIf,因为它完全从dom中删除元素。即使我们等待数据从服务器到达,也不会发生闪烁。

基本上,只要您选择隐藏元素,直到数据到达,每当组件重新初始化,您将看到闪烁。

+0

感谢您的解释。其实,我的问题依然存在。假设数据不会改变(尽管改变了路由,'name'属性是相同的)。它应该保持相同的数据(不闪烁)。我记得在使用RC.4和'ROUTER_DIRECTIVES'时,我有类似的东西,但显然,RC.5的行为发生了变化。我会尽量在稍后发布Plunkr。 – brians69

+0

下面是我期待的行为的Plunker:http://plnkr.co/edit/ZITXyhXAmWWk2hor13ea?p=preview - 我实际上使用RC.5,但是'ROUTER_DIRECTIVES'而不是'RouterModule'。我想知道现在是否可以具有与“ROUTER_DIRECTIVES”相同的行为。 – brians69

+0

@drbishop你原来的代码受到角错误的影响。在导航到相同组件时(即使参数改变),路由器应该重新使用组件的同一个实例。然而,从'Angular rc 5'开始,这种机制在延迟加载的组件上失败,所以即使没有数据改变,你的'PagesComponent'也会被销毁并重新创建。请参阅https://github.com/angular/angular/issues/10987 – BeetleJuice