angular 2 路由订阅变化检测

angular 2 routing subscription change detection

鉴于此代码:

ngOnInit() {
    this.apiService.getBlogPosts().subscribe(blogPosts => {
        this.allBlogPosts = blogPosts;

        this.changeDetector.detectChanges();
    }));
}

我试图理解为什么我被迫使用 this.changeDetector.detectChanges();

情况是,如果我第一次加载我的博客路由,我的 post 加载正常,如果我 route 到另一个页面(另一个 component 或同样 "blog" component 显示特定 post 的详细信息(例如 'blog/my-post'))然后我 route 回到 "blog" 组件root ('blog/'),这一次,模板无法更新 posts。我可以在我的 InspectNetwork 选项卡中看到,获取 post 的路径仍在工作,console.log 显示一切似乎都很好,但是除非我强制更改检测,否则模板无法更新。这是预期的行为吗?可以补救吗?这似乎很奇怪...

另一件值得注意的事情是,我第一次和第三次访问 "blog" component 我使用:

this.router.navigate([`/${url}`]);

导航到它...这没办法...

编辑: getBlogPosts() 方法在我的 ApiService 中,我将其注入 BlogComponent:

public getBlogPosts() : Observable<BlogPost[]> {
    return this.http.get(`${ environment.apiUrl }GetBlogPosts`, { headers: this.headers })
                    .map((response: Response) => <BlogPost[]>response.json());
}

Angular 使用 NgZone 在变更检测周期应为 运行 时得到通知。 NgZone 在引擎盖下使用 zone.js 来拦截所有异步操作,如 setTimeoutnew PromiseXHR 请求等。所以通常它不需要任何额外的努力就可以工作开发商。

但是,如果您的某些操作未被 zone.js 捕获,则您不会触发更改检测,而必须手动执行。但是您可以使用 NgZone 在 Angular 区域中执行一些操作,这意味着 Angular 将在回调完成执行后 运行 更改检测。

所以在你的情况下你可以尝试这样的事情:

this.routerSubject.subscribe((url: string) => { NgZone.run(() => this.router.navigate([/${url}]); });

其中 NgZone 可以注入任何 Angular 组件或服务:

constructor(zone: NgZone) {}