以下代码针对三种不同的路线提供相同的组件
AppComponent
,包括/
,/route2
和/route3
。问题是,
title
的{{1}}和bodyHTML
属性在选择不同路由时不会更改值。需要对下面的代码进行哪些具体更改,以便当用户选择每条不同的路线时,应用会为
AppComponent
和title
提供不同的值?< / strong>以下是在几分钟内 上重现问题的步骤:
首先,我在以下步骤中使用Angular-CLI创建了种子应用程序:
bodyHTML
接下来,我只更改了4个文件,如下所示:
我添加了cd C:\projects\angular-cli
ng new routes-share-component
cd C:\projects\angular-cli\routes-share-component
ng serve
以下内容:
app.routing.ts
我将import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
const appRoutes: Routes = [
{ path: '', component: AppComponent },
{ path: 'route2', component: AppComponent },
{ path: 'route3', component: AppComponent }
];
export const routing = RouterModule.forRoot(appRoutes);
更改为以下内容:
app.component.ts
同样,import { Component, OnInit, OnChanges } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Router } from '@angular/router';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnChanges {
title = 'This is the title!';
bodyHTML = 'Here is the content!'
constructor(private _router:Router, private route:ActivatedRoute) {
console.log('inside the constructor!');
console.log(route.url);
console.log(_router.url);
}
ngOnInit() {
console.log('inside ngOnInit()');
let currentUrl = this._router.url; /// this will give you current url
console.log(currentUrl);
if(currentUrl=='/'){this.title='Home Page Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route2'){this.title='Route 2 Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route3'){this.title='Route 3 Title';this.bodyHTML='Body goes here.';}
console.log(this.route.url);
}
ngOnChanges() {
console.log('inside ngOnChanges()!');
let currentUrl = this._router.url; /// this will give you current url
console.log(currentUrl);
if(currentUrl=='/'){this.title='Home Page Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route2'){this.title='Route 2 Title';this.bodyHTML='Body goes here.';}
if(currentUrl=='/route3'){this.title='Route 3 Title';this.bodyHTML='Body goes here.';}
console.log(this.route.url);
}
}
被简化为以下内容:
app.component.html
<div style="text-align:left">
<h1>{{title}}</h1>
<p>{{bodyHTML}}</p>
</div>
成为以下内容,其中包含app.module.ts
:
app.routing.ts
请注意,import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { routing } from './app.routing';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule, routing
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
块在控制台中打印,但ngOnInit()
块不打印。这意味着无论选择哪条路线,标题始终为ngOnChanges()
。
需要对上述代码进行哪些具体更改,以便每个路径在浏览器中为Home Page Title
和title
打印不同的值?
根据@ BeetleJuice的建议,我尝试了以下新版本的bodyHTML
,但它显示了AppComponent
行和routerSub:Subscription
行的编译错误。
this.routerSub = this.router.events.filter(....)
还需要改变什么?
答案 0 :(得分:2)
您需要认识到的两件事:
当Angular导航到使用相同组件的新路由时,它不会重新初始化组件。因此,ngOnInit
仅在第一次加载组件时运行。
当任何组件属性发生更改时,ngOnChanges 不。当父组件更改数据绑定属性(由@Input() someProp
表示)时,会触发它。 See the docs。因此,您的ngOnChanges
也未被触发。
当路线发生变化但是组件没有注入路由器时更新模型的一种方法是,听取Router.events
可观察量并对路线变化做出反应
<强> app.component.ts 强>
import {NavigationEnd, Router} from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/filter';
...
routerSub:Subscription;
ngOnInit(){
// listen to NavigationEnd events
this.routerSub = this.router.events.filter(e=>e instanceof NavigationEnd)
// capture the new URL
.map((e:NavigationEnd) => e.url)
.subscribe(url => {
/* TODO: use URL to update the view */
});
}
// When the component is destroyed, you must unsubscribe to avoid memory leaks
ngOnDestroy(){
this.routerSub.unsubscribe();
}
顺便说一句,将多个路由解析为同一个组件可能不是一个好主意。考虑改为使用parameterized route!